Add isOwner= input selector for seapp_contexts.
Enable distinctions to be made between the owner/primary user
and secondary users in seapp_contexts.
Change-Id: I37aa5b183a7a617cce68ccf14510c31dfee4e04d
Signed-off-by: Stephen Smalley <sds@tycho.nsa.gov>
diff --git a/src/android.c b/src/android.c
index 2fd1fac..9e5bd02 100644
--- a/src/android.c
+++ b/src/android.c
@@ -158,6 +158,8 @@
struct seapp_context {
/* input selectors */
char isSystemServer;
+ bool isOwnerSet;
+ bool isOwner;
struct prefix_str user;
char *seinfo;
struct prefix_str name;
@@ -195,6 +197,10 @@
if (s1->isSystemServer != s2->isSystemServer)
return (s1->isSystemServer ? -1 : 1);
+ /* Give precedence to a specified isOwner= over an unspecified isOwner=. */
+ if (s1->isOwnerSet != s2->isOwnerSet)
+ return (s1->isOwnerSet ? -1 : 1);
+
/* Give precedence to a specified user= over an unspecified user=. */
if (s1->user.str && !s2->user.str)
return -1;
@@ -353,6 +359,16 @@
free_seapp_context(cur);
goto err;
}
+ } else if (!strcasecmp(name, "isOwner")) {
+ cur->isOwnerSet = true;
+ if (!strcasecmp(value, "true"))
+ cur->isOwner = true;
+ else if (!strcasecmp(value, "false"))
+ cur->isOwner = false;
+ else {
+ free_seapp_context(cur);
+ goto err;
+ }
} else if (!strcasecmp(name, "user")) {
cur->user.str = strdup(value);
if (!cur->user.str) {
@@ -463,12 +479,14 @@
int i;
for (i = 0; i < nspec; i++) {
cur = seapp_contexts[i];
- selinux_log(SELINUX_INFO, "%s: isSystemServer=%s user=%s seinfo=%s name=%s path=%s sebool=%s -> domain=%s type=%s level=%s levelFrom=%s",
- __FUNCTION__,
- cur->isSystemServer ? "true" : "false", cur->user.str,
- cur->seinfo, cur->name.str, cur->path.str, cur->sebool, cur->domain,
- cur->type, cur->level,
- levelFromName[cur->levelFrom]);
+ selinux_log(SELINUX_INFO, "%s: isSystemServer=%s isOwner=%s user=%s seinfo=%s name=%s path=%s sebool=%s -> domain=%s type=%s level=%s levelFrom=%s",
+ __FUNCTION__,
+ cur->isSystemServer ? "true" : "false",
+ cur->isOwnerSet ? (cur->isOwner ? "true" : "false") : "null",
+ cur->user.str,
+ cur->seinfo, cur->name.str, cur->path.str, cur->sebool, cur->domain,
+ cur->type, cur->level,
+ levelFromName[cur->levelFrom]);
}
}
#endif
@@ -520,6 +538,7 @@
const char *path,
context_t ctx)
{
+ bool isOwner;
const char *username = NULL;
struct seapp_context *cur = NULL;
int i;
@@ -530,6 +549,7 @@
__selinux_once(once, seapp_context_init);
userid = uid / AID_USER;
+ isOwner = (userid == 0);
appid = uid % AID_USER;
if (appid < AID_APP) {
for (n = 0; n < android_id_count; n++) {
@@ -557,6 +577,9 @@
if (cur->isSystemServer != isSystemServer)
continue;
+ if (cur->isOwnerSet && cur->isOwner != isOwner)
+ continue;
+
if (cur->user.str) {
if (cur->user.is_prefix) {
if (strncasecmp(username, cur->user.str, cur->user.len-1))