Merge "libselinux: use /proc/thread-self when available"
am: 02df2e3082

* commit '02df2e30820051a4b592071946521d5c9f7eb74b':
  libselinux: use /proc/thread-self when available
diff --git a/src/android.c b/src/android.c
index eb58201..4930888 100644
--- a/src/android.c
+++ b/src/android.c
@@ -168,6 +168,8 @@
 struct seapp_context {
 	/* input selectors */
 	bool isSystemServer;
+	bool isAutoPlayAppSet;
+	bool isAutoPlayApp;
 	bool isOwnerSet;
 	bool isOwner;
 	struct prefix_str user;
@@ -210,6 +212,12 @@
 	if (s1->isSystemServer != s2->isSystemServer)
 		return (s1->isSystemServer ? -1 : 1);
 
+	/* Give precedence to a specified isAutoPlayApp= over an
+	 * unspecified isAutoPlayApp=. */
+	if (s1->isAutoPlayAppSet != s2->isAutoPlayAppSet)
+		return (s1->isAutoPlayAppSet ? -1 : 1);
+
+
 	/* Give precedence to a specified isOwner= over an unspecified isOwner=. */
 	if (s1->isOwnerSet != s2->isOwnerSet)
 		return (s1->isOwnerSet ? -1 : 1);
@@ -393,6 +401,16 @@
 					free_seapp_context(cur);
 					goto err;
 				}
+			} else if (!strcasecmp(name, "isAutoPlayApp")) {
+				cur->isAutoPlayAppSet = true;
+				if (!strcasecmp(value, "true"))
+					cur->isAutoPlayApp = true;
+				else if (!strcasecmp(value, "false"))
+					cur->isAutoPlayApp = false;
+				else {
+					free_seapp_context(cur);
+					goto err;
+				}
 			} else if (!strcasecmp(name, "isOwner")) {
 				cur->isOwnerSet = true;
 				if (!strcasecmp(value, "true"))
@@ -560,9 +578,11 @@
 		int i;
 		for (i = 0; i < nspec; i++) {
 			cur = seapp_contexts[i];
-			selinux_log(SELINUX_INFO, "%s:  isSystemServer=%s isOwner=%s user=%s seinfo=%s name=%s path=%s isPrivApp=%s -> domain=%s type=%s level=%s levelFrom=%s",
+			selinux_log(SELINUX_INFO, "%s:  isSystemServer=%s  isAutoPlayApp=%s isOwner=%s user=%s seinfo=%s "
+					"name=%s path=%s isPrivApp=%s -> domain=%s type=%s level=%s levelFrom=%s",
 				__FUNCTION__,
 				cur->isSystemServer ? "true" : "false",
+				cur->isAutoPlayAppSet ? (cur->isAutoPlayApp ? "true" : "false") : "null",
 				cur->isOwnerSet ? (cur->isOwner ? "true" : "false") : "null",
 				cur->user.str,
 				cur->seinfo, cur->name.str, cur->path.str,
@@ -613,10 +633,7 @@
 };
 
 #define PRIVILEGED_APP_STR ":privapp"
-static bool is_app_privileged(const char *seinfo)
-{
-	return strstr(seinfo, PRIVILEGED_APP_STR) != NULL;
-}
+#define AUTOPLAY_APP_STR ":autoplayapp"
 
 static int seinfo_parse(char *dest, const char *src, size_t size)
 {
@@ -653,6 +670,7 @@
 	uid_t userid;
 	uid_t appid;
 	bool isPrivApp = false;
+	bool isAutoPlayApp = false;
 	char parsedseinfo[BUFSIZ];
 
 	__selinux_once(once, seapp_context_init);
@@ -660,7 +678,8 @@
 	if (seinfo) {
 		if (seinfo_parse(parsedseinfo, seinfo, BUFSIZ))
 			goto err;
-		isPrivApp = is_app_privileged(seinfo);
+		isPrivApp = strstr(seinfo, PRIVILEGED_APP_STR) ? true : false;
+		isAutoPlayApp = strstr(seinfo, AUTOPLAY_APP_STR) ? true : false;
 		seinfo = parsedseinfo;
 	}
 
@@ -693,6 +712,9 @@
 		if (cur->isSystemServer != isSystemServer)
 			continue;
 
+		if (cur->isAutoPlayAppSet && cur->isAutoPlayApp != isAutoPlayApp)
+			continue;
+
 		if (cur->isOwnerSet && cur->isOwner != isOwner)
 			continue;