Check preinstalled app's partition am: be36d71068 am: 44b95e92a7 am: 5ad7961fff am: b777ba8580

Original change: https://android-review.googlesource.com/c/platform/external/selinux/+/2670896

Change-Id: Ia3e7f3532256db6cc7c1ab16d5f412f56c3d863a
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
Inseob Kim 2023-07-26 04:23:21 +00:00 committed by Automerger Merge Worker
commit 45e4f38df0
3 changed files with 82 additions and 3 deletions

View file

@ -93,12 +93,27 @@ static const path_alts_t keystore2_context_paths = { .paths = {
size_t find_existing_files(
const path_alts_t *path_sets,
const char* paths[MAX_CONTEXT_PATHS])
{
return find_existing_files_with_partitions(
path_sets,
paths,
NULL
);
}
size_t find_existing_files_with_partitions(
const path_alts_t *path_sets,
const char* paths[MAX_CONTEXT_PATHS],
const char* partitions[MAX_CONTEXT_PATHS])
{
size_t i, j, len = 0;
for (i = 0; i < MAX_CONTEXT_PATHS; i++) {
for (j = 0; j < MAX_ALT_CONTEXT_PATHS; j++) {
const char* file = path_sets->paths[i][j];
if (file && access(file, R_OK) != -1) {
if (partitions) {
partitions[len] = path_sets->partitions[i];
}
paths[len++] = file;
/* Within each set, only the first valid entry is used */
break;

View file

@ -17,6 +17,7 @@ extern "C" {
#define MAX_ALT_CONTEXT_PATHS 2
typedef struct path_alts {
const char *paths[MAX_CONTEXT_PATHS][MAX_ALT_CONTEXT_PATHS];
const char *partitions[MAX_CONTEXT_PATHS];
} path_alts_t;
/* Within each set of files, adds the first file that is accessible to `paths`.
@ -25,6 +26,14 @@ size_t find_existing_files(
const path_alts_t *path_sets,
const char *paths[MAX_CONTEXT_PATHS]);
/* Within each set of files, adds the first file that is accessible to `paths`.
* Returns the number of accessible files. Also returns the partitions where
* the files exist. */
size_t find_existing_files_with_partitions(
const path_alts_t *path_sets,
const char *paths[MAX_CONTEXT_PATHS],
const char *partitions[MAX_CONTEXT_PATHS]);
/* Converts an array of file paths into an array of options for selabel_open.
* opts must be at least as large as paths. */
void paths_to_opts(

View file

@ -48,8 +48,8 @@ static const path_alts_t file_context_paths = { .paths = {
}
}};
/* Locations for the seapp_contexts files. For each partition, only the first
* existing entry will be used (for example, if
/* Locations for the seapp_contexts files, and corresponding partitions. For
* each partition, only the first existing entry will be used (for example, if
* /system/etc/selinux/plat_seapp_contexts exists, /plat_seapp_contexts will be
* ignored).
*/
@ -77,6 +77,13 @@ static const path_alts_t seapp_context_paths = { .paths = {
"/odm/etc/selinux/odm_seapp_contexts",
"/odm_seapp_contexts"
}
}, .partitions= {
"system",
"system", // regard APEX sepolicy as system
"system_ext",
"product",
"vendor",
"odm"
}};
/* Returns a handle for the file contexts backend, initialized with the Android
@ -141,6 +148,7 @@ struct seapp_context {
char *type;
char *level;
enum levelFrom levelFrom;
const char* partition;
};
static void free_seapp_context(struct seapp_context *s)
@ -273,8 +281,9 @@ int seapp_context_reload_internal(const path_alts_t *context_paths)
size_t i, len, files_len = 0;
int ret;
const char* seapp_contexts_files[MAX_CONTEXT_PATHS];
const char* seapp_contexts_partitions[MAX_CONTEXT_PATHS];
files_len = find_existing_files(context_paths, seapp_contexts_files);
files_len = find_existing_files_with_partitions(context_paths, seapp_contexts_files, seapp_contexts_partitions);
/* Reset the current entries */
free_seapp_contexts();
@ -525,6 +534,7 @@ int seapp_context_reload_internal(const path_alts_t *context_paths)
goto err;
}
cur->partition = seapp_contexts_partitions[i];
seapp_contexts[nspec] = cur;
nspec++;
lineno++;
@ -643,6 +653,7 @@ void selinux_android_seapp_context_init(void) {
#define APPLY_SDK_SANDBOX_NEXT_RESTRICTIONS_STR ":isSdkSandboxNext"
#define EPHEMERAL_APP_STR ":ephemeralapp"
#define TARGETSDKVERSION_STR ":targetSdkVersion="
#define PARTITION_STR ":partition="
#define FROM_RUNAS_STR ":fromRunAs"
static int32_t get_app_targetSdkVersion(const char *seinfo)
{
@ -664,6 +675,39 @@ static int32_t get_app_targetSdkVersion(const char *seinfo)
return 0; /* default to 0 when targetSdkVersion= is not present in seinfo */
}
// returns true if found, false if not found or error
static bool get_partition(const char *seinfo, char partition[], size_t size)
{
if (size == 0) return false;
const char *substr = strstr(seinfo, PARTITION_STR);
if (substr == NULL) return false;
const char *src = substr + strlen(PARTITION_STR);
const char *p = strchr(src, ':');
size_t len = p ? p - src : strlen(src);
if (len > size - 1) return -1;
strncpy(partition, src, len);
partition[len] = '\0';
return true;
}
static bool is_platform(const char *partition) {
// system, system_ext, product are regarded as "platform", whereas vendor
// and odm are regarded as vendor.
if (strcmp(partition, "system") == 0) return true;
if (strcmp(partition, "system_ext") == 0) return true;
if (strcmp(partition, "product") == 0) return true;
return false;
}
static bool check_preinstalled_app_partition(const char *spec, const char *app) {
// We forbid system/system_ext/product installed apps from being labeled with vendor sepolicy.
return !is_platform(spec) && is_platform(app);
}
static int seinfo_parse(char *dest, const char *src, size_t size)
{
size_t len;
@ -742,6 +786,8 @@ int seapp_context_lookup_internal(enum seapp_kind kind,
bool isSdkSandboxNext = false;
int32_t targetSdkVersion = 0;
bool fromRunAs = false;
bool isPreinstalledApp = false;
char partition[BUFSIZ];
char parsedseinfo[BUFSIZ];
if (seinfo) {
@ -753,6 +799,7 @@ int seapp_context_lookup_internal(enum seapp_kind kind,
isSdkSandboxNext = strstr(seinfo, APPLY_SDK_SANDBOX_NEXT_RESTRICTIONS_STR) ? true : false;
fromRunAs = strstr(seinfo, FROM_RUNAS_STR) ? true : false;
targetSdkVersion = get_app_targetSdkVersion(seinfo);
isPreinstalledApp = get_partition(seinfo, partition, BUFSIZ);
if (targetSdkVersion < 0) {
selinux_log(SELINUX_ERROR,
"%s: Invalid targetSdkVersion passed for app with uid %d, seinfo %s, name %s\n",
@ -849,6 +896,14 @@ int seapp_context_lookup_internal(enum seapp_kind kind,
}
if (cur->levelFrom != LEVELFROM_NONE) {
if (isPreinstalledApp
&& !check_preinstalled_app_partition(cur->partition, partition)) {
// TODO(b/280547417): make this an error after fixing violations
selinux_log(SELINUX_ERROR,
"%s: App %s preinstalled to %s can't be labeled with %s sepolicy",
__FUNCTION__, pkgname, partition, cur->partition);
}
int res = set_range_from_level(ctx, cur->levelFrom, userid, appid);
if (res != 0) {
return res;