Use generic isSelector am: 3d85f1e116
am: bce1d3689b
am: 28f879de16
Original change: https://android-review.googlesource.com/c/platform/external/selinux/+/2839485 Change-Id: I067484d72885ba209b0944a326474b2008cec004 Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
commit
2e514132bf
3 changed files with 144 additions and 153 deletions
|
@ -105,14 +105,7 @@ int seapp_context_reload_internal(const path_alts_t *context_paths);
|
||||||
/* A parsed seinfo */
|
/* A parsed seinfo */
|
||||||
struct parsed_seinfo {
|
struct parsed_seinfo {
|
||||||
char base[SEINFO_BUFSIZ];
|
char base[SEINFO_BUFSIZ];
|
||||||
#define IS_PRIV_APP (1 << 0)
|
char isSelector[SEINFO_BUFSIZ];
|
||||||
#define IS_FROM_RUN_AS (1 << 1)
|
|
||||||
#define IS_EPHEMERAL_APP (1 << 2)
|
|
||||||
#define IS_ISOLATED_COMPUTE_APP (1 << 3)
|
|
||||||
#define IS_SDK_SANDBOX_AUDIT (1 << 4)
|
|
||||||
#define IS_SDK_SANDBOX_NEXT (1 << 5)
|
|
||||||
int32_t is;
|
|
||||||
bool isPreinstalledApp;
|
|
||||||
char partition[SEINFO_BUFSIZ];
|
char partition[SEINFO_BUFSIZ];
|
||||||
int32_t targetSdkVersion;
|
int32_t targetSdkVersion;
|
||||||
};
|
};
|
||||||
|
|
|
@ -128,18 +128,14 @@ static void free_prefix_str(struct prefix_str *p)
|
||||||
struct seapp_context {
|
struct seapp_context {
|
||||||
/* input selectors */
|
/* input selectors */
|
||||||
bool isSystemServer;
|
bool isSystemServer;
|
||||||
bool isEphemeralAppSet;
|
|
||||||
bool isEphemeralApp;
|
|
||||||
struct prefix_str user;
|
struct prefix_str user;
|
||||||
char *seinfo;
|
char *seinfo;
|
||||||
struct prefix_str name;
|
struct prefix_str name;
|
||||||
bool isPrivAppSet;
|
|
||||||
bool isPrivApp;
|
|
||||||
int32_t minTargetSdkVersion;
|
int32_t minTargetSdkVersion;
|
||||||
bool fromRunAs;
|
/* name of a boolean selector such as isPrivApp, fromRunAs,
|
||||||
bool isIsolatedComputeApp;
|
* isIsolatedComputeApp, etc. */
|
||||||
bool isSdkSandboxAudit;
|
char *isSelector;
|
||||||
bool isSdkSandboxNext;
|
bool isSelectorValue;
|
||||||
/* outputs */
|
/* outputs */
|
||||||
char *domain;
|
char *domain;
|
||||||
char *type;
|
char *type;
|
||||||
|
@ -153,6 +149,7 @@ static void free_seapp_context(struct seapp_context *s)
|
||||||
if (!s)
|
if (!s)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
free(s->isSelector);
|
||||||
free_prefix_str(&s->user);
|
free_prefix_str(&s->user);
|
||||||
free(s->seinfo);
|
free(s->seinfo);
|
||||||
free_prefix_str(&s->name);
|
free_prefix_str(&s->name);
|
||||||
|
@ -181,11 +178,6 @@ static int seapp_context_cmp(const void *A, const void *B)
|
||||||
if (s1->isSystemServer != s2->isSystemServer)
|
if (s1->isSystemServer != s2->isSystemServer)
|
||||||
return (s1->isSystemServer ? -1 : 1);
|
return (s1->isSystemServer ? -1 : 1);
|
||||||
|
|
||||||
/* Give precedence to a specified isEphemeral= over an
|
|
||||||
* unspecified isEphemeral=. */
|
|
||||||
if (s1->isEphemeralAppSet != s2->isEphemeralAppSet)
|
|
||||||
return (s1->isEphemeralAppSet ? -1 : 1);
|
|
||||||
|
|
||||||
/* Give precedence to a specified user= over an unspecified user=. */
|
/* Give precedence to a specified user= over an unspecified user=. */
|
||||||
if (s1->user.str && !s2->user.str)
|
if (s1->user.str && !s2->user.str)
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -224,9 +216,12 @@ static int seapp_context_cmp(const void *A, const void *B)
|
||||||
return (s1->name.len > s2->name.len) ? -1 : 1;
|
return (s1->name.len > s2->name.len) ? -1 : 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Give precedence to a specified isPrivApp= over an unspecified isPrivApp=. */
|
/* Give precedence to a specified isSelector (e.g., isPrivApp)
|
||||||
if (s1->isPrivAppSet != s2->isPrivAppSet)
|
* over an unspecified isSelector. */
|
||||||
return (s1->isPrivAppSet ? -1 : 1);
|
if(s1->isSelector && !s2->isSelector)
|
||||||
|
return -1;
|
||||||
|
if(!s1->isSelector && s2->isSelector)
|
||||||
|
return 1;
|
||||||
|
|
||||||
/* Give precedence to a higher minTargetSdkVersion= over a lower minTargetSdkVersion=.
|
/* Give precedence to a higher minTargetSdkVersion= over a lower minTargetSdkVersion=.
|
||||||
* If unspecified, minTargetSdkVersion has a default value of 0.
|
* If unspecified, minTargetSdkVersion has a default value of 0.
|
||||||
|
@ -236,10 +231,6 @@ static int seapp_context_cmp(const void *A, const void *B)
|
||||||
else if (s1->minTargetSdkVersion < s2->minTargetSdkVersion)
|
else if (s1->minTargetSdkVersion < s2->minTargetSdkVersion)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
/* Give precedence to fromRunAs=true. */
|
|
||||||
if (s1->fromRunAs != s2->fromRunAs)
|
|
||||||
return (s1->fromRunAs ? -1 : 1);
|
|
||||||
|
|
||||||
/* Give precedence to platform side contexts */
|
/* Give precedence to platform side contexts */
|
||||||
bool isS1Platform = is_platform(s1->partition);
|
bool isS1Platform = is_platform(s1->partition);
|
||||||
bool isS2Platform = is_platform(s2->partition);
|
bool isS2Platform = is_platform(s2->partition);
|
||||||
|
@ -375,16 +366,6 @@ int seapp_context_reload_internal(const path_alts_t *context_paths)
|
||||||
free_seapp_context(cur);
|
free_seapp_context(cur);
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
} else if (!strcasecmp(name, "isEphemeralApp")) {
|
|
||||||
cur->isEphemeralAppSet = true;
|
|
||||||
if (!strcasecmp(value, "true"))
|
|
||||||
cur->isEphemeralApp = true;
|
|
||||||
else if (!strcasecmp(value, "false"))
|
|
||||||
cur->isEphemeralApp = false;
|
|
||||||
else {
|
|
||||||
free_seapp_context(cur);
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
} else if (!strcasecmp(name, "user")) {
|
} else if (!strcasecmp(name, "user")) {
|
||||||
if (cur->user.str) {
|
if (cur->user.str) {
|
||||||
free_seapp_context(cur);
|
free_seapp_context(cur);
|
||||||
|
@ -485,55 +466,30 @@ int seapp_context_reload_internal(const path_alts_t *context_paths)
|
||||||
free_seapp_context(cur);
|
free_seapp_context(cur);
|
||||||
goto oom;
|
goto oom;
|
||||||
}
|
}
|
||||||
} else if (!strcasecmp(name, "isPrivApp")) {
|
|
||||||
cur->isPrivAppSet = true;
|
|
||||||
if (!strcasecmp(value, "true"))
|
|
||||||
cur->isPrivApp = true;
|
|
||||||
else if (!strcasecmp(value, "false"))
|
|
||||||
cur->isPrivApp = false;
|
|
||||||
else {
|
|
||||||
free_seapp_context(cur);
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
} else if (!strcasecmp(name, "minTargetSdkVersion")) {
|
} else if (!strcasecmp(name, "minTargetSdkVersion")) {
|
||||||
cur->minTargetSdkVersion = get_minTargetSdkVersion(value);
|
cur->minTargetSdkVersion = get_minTargetSdkVersion(value);
|
||||||
if (cur->minTargetSdkVersion < 0) {
|
if (cur->minTargetSdkVersion < 0) {
|
||||||
free_seapp_context(cur);
|
free_seapp_context(cur);
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
} else if (!strcasecmp(name, "fromRunAs")) {
|
} else if ((!strncasecmp(name, "is", 2) && strlen(name) > 3) ||
|
||||||
if (!strcasecmp(value, "true"))
|
!strcasecmp(name, "fromRunAs")) {
|
||||||
cur->fromRunAs = true;
|
if (cur->isSelector) {
|
||||||
else if (!strcasecmp(value, "false"))
|
selinux_log(SELINUX_ERROR, "%s: isSelector set twice %s",
|
||||||
cur->fromRunAs = false;
|
__FUNCTION__, name);
|
||||||
else {
|
|
||||||
free_seapp_context(cur);
|
free_seapp_context(cur);
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
} else if (!strcasecmp(name, "isIsolatedComputeApp")) {
|
cur->isSelector = strdup(name);
|
||||||
if (!strcasecmp(value, "true"))
|
if (!cur->isSelector) {
|
||||||
cur->isIsolatedComputeApp = true;
|
|
||||||
else if (!strcasecmp(value, "false"))
|
|
||||||
cur->isIsolatedComputeApp = false;
|
|
||||||
else {
|
|
||||||
free_seapp_context(cur);
|
free_seapp_context(cur);
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
} else if (!strcasecmp(name, "isSdkSandboxAudit")) {
|
if (!strcasecmp(value, "true")) {
|
||||||
if (!strcasecmp(value, "true"))
|
cur->isSelectorValue = true;
|
||||||
cur->isSdkSandboxAudit = true;
|
} else if (!strcasecmp(value, "false")) {
|
||||||
else if (!strcasecmp(value, "false"))
|
cur->isSelectorValue = false;
|
||||||
cur->isSdkSandboxAudit = false;
|
} else {
|
||||||
else {
|
|
||||||
free_seapp_context(cur);
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
} else if (!strcasecmp(name, "isSdkSandboxNext")) {
|
|
||||||
if (!strcasecmp(value, "true"))
|
|
||||||
cur->isSdkSandboxNext = true;
|
|
||||||
else if (!strcasecmp(value, "false"))
|
|
||||||
cur->isSdkSandboxNext = false;
|
|
||||||
else {
|
|
||||||
free_seapp_context(cur);
|
free_seapp_context(cur);
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
@ -547,7 +503,8 @@ int seapp_context_reload_internal(const path_alts_t *context_paths)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!cur->isPrivApp && cur->name.str &&
|
if ((!cur->isSelector || strcasecmp(cur->isSelector, "isPrivApp") || !cur->isSelectorValue) &&
|
||||||
|
cur->name.str &&
|
||||||
(!cur->seinfo || !strcmp(cur->seinfo, "default"))) {
|
(!cur->seinfo || !strcmp(cur->seinfo, "default"))) {
|
||||||
selinux_log(SELINUX_ERROR, "%s: No specific seinfo value specified with name=\"%s\", on line %u: insecure configuration!\n",
|
selinux_log(SELINUX_ERROR, "%s: No specific seinfo value specified with name=\"%s\", on line %u: insecure configuration!\n",
|
||||||
seapp_contexts_files[i], cur->name.str, lineno);
|
seapp_contexts_files[i], cur->name.str, lineno);
|
||||||
|
@ -582,11 +539,8 @@ int seapp_context_reload_internal(const path_alts_t *context_paths)
|
||||||
bool dup = (!s1->user.str || !strcmp(s1->user.str, s2->user.str)) &&
|
bool dup = (!s1->user.str || !strcmp(s1->user.str, s2->user.str)) &&
|
||||||
(!s1->seinfo || !strcmp(s1->seinfo, s2->seinfo)) &&
|
(!s1->seinfo || !strcmp(s1->seinfo, s2->seinfo)) &&
|
||||||
(!s1->name.str || !strcmp(s1->name.str, s2->name.str)) &&
|
(!s1->name.str || !strcmp(s1->name.str, s2->name.str)) &&
|
||||||
(!s1->isPrivAppSet || s1->isPrivApp == s2->isPrivApp) &&
|
(!s1->isSelector || !strcmp(s1->isSelector, s2->isSelector)) &&
|
||||||
(!s1->isEphemeralAppSet || s1->isEphemeralApp == s2->isEphemeralApp) &&
|
(s1->isSelectorValue == s2->isSelectorValue);
|
||||||
(s1->isIsolatedComputeApp == s2->isIsolatedComputeApp) &&
|
|
||||||
(s1->isSdkSandboxAudit == s2->isSdkSandboxAudit) &&
|
|
||||||
(s1->isSdkSandboxNext == s2->isSdkSandboxNext);
|
|
||||||
|
|
||||||
if (dup) {
|
if (dup) {
|
||||||
selinux_log(SELINUX_ERROR, "seapp_contexts: Duplicated entry\n");
|
selinux_log(SELINUX_ERROR, "seapp_contexts: Duplicated entry\n");
|
||||||
|
@ -608,27 +562,21 @@ int seapp_context_reload_internal(const path_alts_t *context_paths)
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < nspec; i++) {
|
for (i = 0; i < nspec; i++) {
|
||||||
cur = seapp_contexts[i];
|
cur = seapp_contexts[i];
|
||||||
selinux_log(SELINUX_INFO, "%s: isSystemServer=%s isEphemeralApp=%s "
|
selinux_log(SELINUX_INFO, "%s: isSystemServer=%s %s=%s "
|
||||||
"isIsolatedComputeApp=%s isSdkSandboxAudit=%s isSdkSandboxNext=%s "
|
"user=%s seinfo=%s name=%s minTargetSdkVersion=%d "
|
||||||
"user=%s seinfo=%s name=%s isPrivApp=%s minTargetSdkVersion=%d "
|
" -> domain=%s type=%s level=%s levelFrom=%s",
|
||||||
"fromRunAs=%s -> domain=%s type=%s level=%s levelFrom=%s",
|
|
||||||
__FUNCTION__,
|
__FUNCTION__,
|
||||||
cur->isSystemServer ? "true" : "false",
|
cur->isSystemServer ? "true" : "false",
|
||||||
cur->isEphemeralAppSet ? (cur->isEphemeralApp ? "true" : "false") : "null",
|
cur->isSelector ? cur->isSelector : "isX",
|
||||||
|
cur->isSelector ? (cur->isSelectorValue ? "true" : "false") : "null",
|
||||||
cur->user.str,
|
cur->user.str,
|
||||||
cur->seinfo, cur->name.str,
|
cur->seinfo, cur->name.str,
|
||||||
cur->isPrivAppSet ? (cur->isPrivApp ? "true" : "false") : "null",
|
|
||||||
cur->minTargetSdkVersion,
|
cur->minTargetSdkVersion,
|
||||||
cur->fromRunAs ? "true" : "false",
|
|
||||||
cur->isIsolatedComputeApp ? "true" : "false",
|
|
||||||
cur->isSdkSandboxAudit ? "true" : "false",
|
|
||||||
cur->isSdkSandboxNext ? "true" : "false",
|
|
||||||
cur->domain, cur->type, cur->level,
|
cur->domain, cur->type, cur->level,
|
||||||
levelFromName[cur->levelFrom]);
|
levelFromName[cur->levelFrom]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ret = 0;
|
ret = 0;
|
||||||
|
|
||||||
out:
|
out:
|
||||||
|
@ -675,16 +623,21 @@ void selinux_android_seapp_context_init(void) {
|
||||||
*/
|
*/
|
||||||
#define CAT_MAPPING_MAX_ID (0x1<<16)
|
#define CAT_MAPPING_MAX_ID (0x1<<16)
|
||||||
|
|
||||||
#define PRIVILEGED_APP_STR "privapp"
|
|
||||||
#define ISOLATED_COMPUTE_APP_STR "isolatedComputeApp"
|
|
||||||
#define APPLY_SDK_SANDBOX_AUDIT_RESTRICTIONS_STR "isSdkSandboxAudit"
|
|
||||||
#define APPLY_SDK_SANDBOX_NEXT_RESTRICTIONS_STR "isSdkSandboxNext"
|
|
||||||
#define EPHEMERAL_APP_STR "ephemeralapp"
|
|
||||||
#define TARGETSDKVERSION_STR "targetSdkVersion"
|
#define TARGETSDKVERSION_STR "targetSdkVersion"
|
||||||
#define PARTITION_STR "partition"
|
#define PARTITION_STR "partition"
|
||||||
#define FROM_RUNAS_STR "fromRunAs"
|
|
||||||
#define COMPLETE_STR "complete"
|
#define COMPLETE_STR "complete"
|
||||||
|
|
||||||
|
/* Any selector from seapp_contexts starting with "is" is automatically mapped
|
||||||
|
* to an attribute of seinfo. For historical reasons, there are mappings that do
|
||||||
|
* not follow this convention. */
|
||||||
|
static char* selector_mappings[][2] = {
|
||||||
|
/* seinfo field, seapp_contexts selector */
|
||||||
|
{"privapp", "isPrivApp"},
|
||||||
|
{"isolatedComputeApp", "isIsolatedComputeApp"},
|
||||||
|
{"ephemeralapp", "isEphemeralApp"},
|
||||||
|
{"fromRunAs", "fromRunAs"}
|
||||||
|
};
|
||||||
|
|
||||||
static bool is_preinstalled_app_partition_valid(const char *app_policy, const char *app_partition) {
|
static bool is_preinstalled_app_partition_valid(const char *app_policy, const char *app_partition) {
|
||||||
// We forbid system/system_ext/product installed apps from being labeled with vendor sepolicy.
|
// We forbid system/system_ext/product installed apps from being labeled with vendor sepolicy.
|
||||||
// So, either the app shouldn't be platform, or the spec should be platform.
|
// So, either the app shouldn't be platform, or the spec should be platform.
|
||||||
|
@ -725,6 +678,8 @@ int set_range_from_level(context_t ctx, enum levelFrom levelFrom, uid_t userid,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
|
||||||
|
|
||||||
int parse_seinfo(const char* seinfo, struct parsed_seinfo* info) {
|
int parse_seinfo(const char* seinfo, struct parsed_seinfo* info) {
|
||||||
char local_seinfo[SEINFO_BUFSIZ];
|
char local_seinfo[SEINFO_BUFSIZ];
|
||||||
|
|
||||||
|
@ -747,28 +702,29 @@ int parse_seinfo(const char* seinfo, struct parsed_seinfo* info) {
|
||||||
first = false;
|
first = false;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (!strcmp(token, PRIVILEGED_APP_STR)) {
|
bool matched = false;
|
||||||
info->is |= IS_PRIV_APP;
|
for (int i=0; i < ARRAY_SIZE(selector_mappings); i++) {
|
||||||
|
if (!strcmp(token, selector_mappings[i][0])) {
|
||||||
|
if(info->isSelector[0]) {
|
||||||
|
selinux_log(SELINUX_ERROR, "%s: isSelector already populated: %s in %s\n",
|
||||||
|
__FUNCTION__, token, seinfo);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
strcpy(info->isSelector, selector_mappings[i][1]);
|
||||||
|
matched = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (matched) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (!strcmp(token, EPHEMERAL_APP_STR)) {
|
if (!strncmp(token, "is", 2)) {
|
||||||
info->is |= IS_EPHEMERAL_APP;
|
if(info->isSelector[0]) {
|
||||||
continue;
|
selinux_log(SELINUX_ERROR, "%s: isSelector already populated: %s in %s\n",
|
||||||
|
__FUNCTION__, token, seinfo);
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
if (!strcmp(token, ISOLATED_COMPUTE_APP_STR)) {
|
strncpy(info->isSelector, token, strlen(token));
|
||||||
info->is |= IS_ISOLATED_COMPUTE_APP;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (!strcmp(token, APPLY_SDK_SANDBOX_AUDIT_RESTRICTIONS_STR)) {
|
|
||||||
info->is |= IS_SDK_SANDBOX_AUDIT;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (!strcmp(token, APPLY_SDK_SANDBOX_NEXT_RESTRICTIONS_STR)) {
|
|
||||||
info->is |= IS_SDK_SANDBOX_NEXT;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (!strcmp(token, FROM_RUNAS_STR)) {
|
|
||||||
info->is |= IS_FROM_RUN_AS;
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (!strncmp(token, TARGETSDKVERSION_STR, strlen(TARGETSDKVERSION_STR))) {
|
if (!strncmp(token, TARGETSDKVERSION_STR, strlen(TARGETSDKVERSION_STR))) {
|
||||||
|
@ -792,7 +748,6 @@ int parse_seinfo(const char* seinfo, struct parsed_seinfo* info) {
|
||||||
__FUNCTION__, token, seinfo);
|
__FUNCTION__, token, seinfo);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
info->isPreinstalledApp = true;
|
|
||||||
strncpy(info->partition, subtoken, strlen(subtoken));
|
strncpy(info->partition, subtoken, strlen(subtoken));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -868,9 +823,6 @@ int seapp_context_lookup_internal(enum seapp_kind kind,
|
||||||
if (cur->isSystemServer != isSystemServer)
|
if (cur->isSystemServer != isSystemServer)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (cur->isEphemeralAppSet && cur->isEphemeralApp != ((info.is & IS_EPHEMERAL_APP) != 0))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (cur->user.str) {
|
if (cur->user.str) {
|
||||||
if (cur->user.is_prefix) {
|
if (cur->user.is_prefix) {
|
||||||
if (strncasecmp(username, cur->user.str, cur->user.len-1))
|
if (strncasecmp(username, cur->user.str, cur->user.len-1))
|
||||||
|
@ -899,23 +851,16 @@ int seapp_context_lookup_internal(enum seapp_kind kind,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cur->isPrivAppSet && cur->isPrivApp != ((info.is & IS_PRIV_APP) != 0))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (cur->minTargetSdkVersion > info.targetSdkVersion)
|
if (cur->minTargetSdkVersion > info.targetSdkVersion)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (cur->fromRunAs != ((info.is & IS_FROM_RUN_AS) != 0))
|
if (cur->isSelector && cur->isSelectorValue) {
|
||||||
|
if (!info.isSelector[0])
|
||||||
continue;
|
continue;
|
||||||
|
if (strcasecmp(info.isSelector, cur->isSelector)) {
|
||||||
if (cur->isIsolatedComputeApp != ((info.is & IS_ISOLATED_COMPUTE_APP) != 0))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (cur->isSdkSandboxAudit != ((info.is & IS_SDK_SANDBOX_AUDIT) != 0))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (cur->isSdkSandboxNext != ((info.is & IS_SDK_SANDBOX_NEXT) != 0))
|
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (kind == SEAPP_TYPE && !cur->type)
|
if (kind == SEAPP_TYPE && !cur->type)
|
||||||
continue;
|
continue;
|
||||||
|
@ -940,7 +885,7 @@ int seapp_context_lookup_internal(enum seapp_kind kind,
|
||||||
goto oom;
|
goto oom;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (info.isPreinstalledApp
|
if (info.partition[0]
|
||||||
&& !is_preinstalled_app_partition_valid(cur->partition, info.partition)) {
|
&& !is_preinstalled_app_partition_valid(cur->partition, info.partition)) {
|
||||||
// TODO(b/280547417): make this an error after fixing violations
|
// TODO(b/280547417): make this an error after fixing violations
|
||||||
selinux_log(SELINUX_WARNING,
|
selinux_log(SELINUX_WARNING,
|
||||||
|
|
|
@ -12,7 +12,16 @@ using std::string;
|
||||||
|
|
||||||
class AndroidSELinuxTest : public ::testing::Test {
|
class AndroidSELinuxTest : public ::testing::Test {
|
||||||
protected:
|
protected:
|
||||||
|
void SetUp() override {
|
||||||
|
default_seapp_context_ = StringPrintf("%s/seapp_contexts", tdir_.path);
|
||||||
|
default_seapp_path_alts_ = { .paths = {
|
||||||
|
{ default_seapp_context_.c_str() }
|
||||||
|
}};
|
||||||
|
}
|
||||||
|
|
||||||
TemporaryDir tdir_;
|
TemporaryDir tdir_;
|
||||||
|
string default_seapp_context_;
|
||||||
|
path_alts_t default_seapp_path_alts_;
|
||||||
};
|
};
|
||||||
|
|
||||||
TEST_F(AndroidSELinuxTest, LoadAndLookupServiceContext)
|
TEST_F(AndroidSELinuxTest, LoadAndLookupServiceContext)
|
||||||
|
@ -84,19 +93,13 @@ TEST_F(AndroidSELinuxTest, FailLoadingServiceContext)
|
||||||
|
|
||||||
TEST_F(AndroidSELinuxTest, LoadAndLookupSeAppContext)
|
TEST_F(AndroidSELinuxTest, LoadAndLookupSeAppContext)
|
||||||
{
|
{
|
||||||
string seapp_contexts =
|
|
||||||
StringPrintf("%s/seapp_contexts", tdir_.path);
|
|
||||||
|
|
||||||
WriteStringToFile(
|
WriteStringToFile(
|
||||||
"# some comment\n"
|
"# some comment\n"
|
||||||
"user=_app seinfo=platform domain=platform_app type=app_data_file levelFrom=user\n",
|
"user=_app seinfo=platform domain=platform_app type=app_data_file levelFrom=user\n",
|
||||||
seapp_contexts);
|
default_seapp_context_);
|
||||||
|
|
||||||
const path_alts_t seapp_paths = { .paths = {
|
EXPECT_EQ(seapp_context_reload_internal(&default_seapp_path_alts_), 0);
|
||||||
{ seapp_contexts.c_str() }
|
|
||||||
}};
|
|
||||||
|
|
||||||
EXPECT_EQ(seapp_context_reload_internal(&seapp_paths), 0);
|
|
||||||
|
|
||||||
context_t ctx = context_new("u:r:unknown");
|
context_t ctx = context_new("u:r:unknown");
|
||||||
int ret = seapp_context_lookup_internal(SEAPP_DOMAIN, 10001, false, "platform", "com.android.test1", ctx);
|
int ret = seapp_context_lookup_internal(SEAPP_DOMAIN, 10001, false, "platform", "com.android.test1", ctx);
|
||||||
|
@ -111,6 +114,42 @@ TEST_F(AndroidSELinuxTest, LoadAndLookupSeAppContext)
|
||||||
context_free(ctx);
|
context_free(ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(AndroidSELinuxTest, LoadSeAppContextInsecure)
|
||||||
|
{
|
||||||
|
WriteStringToFile(
|
||||||
|
"user=_app name=com.android.test domain=platform_app type=app_data_file\n",
|
||||||
|
default_seapp_context_);
|
||||||
|
|
||||||
|
EXPECT_EQ(seapp_context_reload_internal(&default_seapp_path_alts_), -1);
|
||||||
|
|
||||||
|
WriteStringToFile(
|
||||||
|
"user=_app name=com.android.test isSdkSandbox=true domain=platform_app type=app_data_file\n",
|
||||||
|
default_seapp_context_);
|
||||||
|
|
||||||
|
EXPECT_EQ(seapp_context_reload_internal(&default_seapp_path_alts_), -1);
|
||||||
|
|
||||||
|
WriteStringToFile(
|
||||||
|
"user=_app isPrivApp=false name=com.android.test domain=platform_app type=app_data_file\n",
|
||||||
|
default_seapp_context_);
|
||||||
|
|
||||||
|
EXPECT_EQ(seapp_context_reload_internal(&default_seapp_path_alts_), -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(AndroidSELinuxTest, LoadSeAppContextInsecureWithSeInfoOrPrivApp)
|
||||||
|
{
|
||||||
|
WriteStringToFile(
|
||||||
|
"user=_app isPrivApp=true name=com.android.test domain=platform_app type=app_data_file\n",
|
||||||
|
default_seapp_context_);
|
||||||
|
|
||||||
|
EXPECT_EQ(seapp_context_reload_internal(&default_seapp_path_alts_), 0);
|
||||||
|
|
||||||
|
WriteStringToFile(
|
||||||
|
"user=_app seinfo=platform name=com.android.test domain=platform_app type=app_data_file\n",
|
||||||
|
default_seapp_context_);
|
||||||
|
|
||||||
|
EXPECT_EQ(seapp_context_reload_internal(&default_seapp_path_alts_), 0);
|
||||||
|
}
|
||||||
|
|
||||||
TEST(AndroidSeAppTest, ParseValidSeInfo)
|
TEST(AndroidSeAppTest, ParseValidSeInfo)
|
||||||
{
|
{
|
||||||
struct parsed_seinfo info;
|
struct parsed_seinfo info;
|
||||||
|
@ -122,8 +161,7 @@ TEST(AndroidSeAppTest, ParseValidSeInfo)
|
||||||
EXPECT_EQ(ret, 0);
|
EXPECT_EQ(ret, 0);
|
||||||
EXPECT_STREQ(info.base, "default");
|
EXPECT_STREQ(info.base, "default");
|
||||||
EXPECT_EQ(info.targetSdkVersion, 10000);
|
EXPECT_EQ(info.targetSdkVersion, 10000);
|
||||||
EXPECT_EQ(info.is, IS_PRIV_APP);
|
EXPECT_STREQ(info.isSelector, "isPrivApp");
|
||||||
EXPECT_EQ(info.isPreinstalledApp, true);
|
|
||||||
EXPECT_STREQ(info.partition, "system");
|
EXPECT_STREQ(info.partition, "system");
|
||||||
|
|
||||||
seinfo = "platform:ephemeralapp:partition=system:complete";
|
seinfo = "platform:ephemeralapp:partition=system:complete";
|
||||||
|
@ -132,8 +170,7 @@ TEST(AndroidSeAppTest, ParseValidSeInfo)
|
||||||
EXPECT_EQ(ret, 0);
|
EXPECT_EQ(ret, 0);
|
||||||
EXPECT_STREQ(info.base, "platform");
|
EXPECT_STREQ(info.base, "platform");
|
||||||
EXPECT_EQ(info.targetSdkVersion, 0);
|
EXPECT_EQ(info.targetSdkVersion, 0);
|
||||||
EXPECT_EQ(info.is, IS_EPHEMERAL_APP);
|
EXPECT_STREQ(info.isSelector, "isEphemeralApp");
|
||||||
EXPECT_EQ(info.isPreinstalledApp, true);
|
|
||||||
EXPECT_STREQ(info.partition, "system");
|
EXPECT_STREQ(info.partition, "system");
|
||||||
|
|
||||||
seinfo = "bluetooth";
|
seinfo = "bluetooth";
|
||||||
|
@ -142,8 +179,16 @@ TEST(AndroidSeAppTest, ParseValidSeInfo)
|
||||||
EXPECT_EQ(ret, 0);
|
EXPECT_EQ(ret, 0);
|
||||||
EXPECT_STREQ(info.base, "bluetooth");
|
EXPECT_STREQ(info.base, "bluetooth");
|
||||||
EXPECT_EQ(info.targetSdkVersion, 0);
|
EXPECT_EQ(info.targetSdkVersion, 0);
|
||||||
EXPECT_EQ(info.isPreinstalledApp, false);
|
EXPECT_STREQ(info.isSelector, "");
|
||||||
EXPECT_EQ(info.is, 0);
|
|
||||||
|
seinfo = "default:isSdkSandboxNext:partition=system:complete";
|
||||||
|
ret = parse_seinfo(seinfo.c_str(), &info);
|
||||||
|
|
||||||
|
EXPECT_EQ(ret, 0);
|
||||||
|
EXPECT_STREQ(info.base, "default");
|
||||||
|
EXPECT_EQ(info.targetSdkVersion, 0);
|
||||||
|
EXPECT_STREQ(info.isSelector, "isSdkSandboxNext");
|
||||||
|
EXPECT_STREQ(info.partition, "system");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(AndroidSeAppTest, ParseInvalidSeInfo)
|
TEST(AndroidSeAppTest, ParseInvalidSeInfo)
|
||||||
|
@ -157,6 +202,14 @@ TEST(AndroidSeAppTest, ParseInvalidSeInfo)
|
||||||
seinfo = "default:targetSdkVersion=:complete";
|
seinfo = "default:targetSdkVersion=:complete";
|
||||||
ret = parse_seinfo(seinfo.c_str(), &info);
|
ret = parse_seinfo(seinfo.c_str(), &info);
|
||||||
EXPECT_EQ(ret, -1);
|
EXPECT_EQ(ret, -1);
|
||||||
|
|
||||||
|
seinfo = "default:privapp:ephemeralapp:complete";
|
||||||
|
ret = parse_seinfo(seinfo.c_str(), &info);
|
||||||
|
EXPECT_EQ(ret, -1);
|
||||||
|
|
||||||
|
seinfo = "default:isANewSelector:isAnotherOne:complete";
|
||||||
|
ret = parse_seinfo(seinfo.c_str(), &info);
|
||||||
|
EXPECT_EQ(ret, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(AndroidSeAppTest, ParseOverflow)
|
TEST(AndroidSeAppTest, ParseOverflow)
|
||||||
|
|
Loading…
Reference in a new issue