diff options
author | ThiƩbaud Weksteen <tweek@google.com> | 2024-05-01 14:29:56 +1000 |
---|---|---|
committer | ThiƩbaud Weksteen <tweek@google.com> | 2024-05-06 12:12:31 +1000 |
commit | 62ca57dac973d53e7d51333b2794aa68a022b060 (patch) | |
tree | 2ecc69e5844acba8d0669bdb2eccdaef2452f4ae | |
parent | 261afd394b622a6d9d639978dffcfde84967788c (diff) | |
download | selinux-62ca57dac973d53e7d51333b2794aa68a022b060.tar.gz |
Move is_app_data_path and extract_pkgname_and_userid
Move these functions as-is into android.c so they can be used in the
unit tests. The functions have not been modified, this is a no-op.
Test: build
Bug: 317296680
Change-Id: Icb1e5501a4a337573d24be894a31c0db72ae8acd
-rw-r--r-- | libselinux/src/android/android.c | 182 | ||||
-rw-r--r-- | libselinux/src/android/android_device.c | 188 | ||||
-rw-r--r-- | libselinux/src/android/android_internal.h | 13 |
3 files changed, 195 insertions, 188 deletions
diff --git a/libselinux/src/android/android.c b/libselinux/src/android/android.c index 83066118..de5a2805 100644 --- a/libselinux/src/android/android.c +++ b/libselinux/src/android/android.c @@ -1,4 +1,5 @@ #include <errno.h> +#include <fnmatch.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> @@ -188,6 +189,187 @@ struct selabel_handle* selinux_android_keystore2_key_context_handle(void) return context_handle(SELABEL_CTX_ANDROID_KEYSTORE2_KEY, &keystore2_context_paths, "keystore2"); } +/* The path prefixes of package data directories. */ +#define DATA_DATA_PATH "/data/data" +#define DATA_USER_PATH "/data/user" +#define DATA_USER_DE_PATH "/data/user_de" +#define DATA_MISC_CE_PATH "/data/misc_ce" +#define DATA_MISC_DE_PATH "/data/misc_de" +#define DATA_STORAGE_AREA_PATH "/data/storage_area" +#define SDK_SANDBOX_DATA_CE_PATH "/data/misc_ce/*/sdksandbox" +#define SDK_SANDBOX_DATA_DE_PATH "/data/misc_de/*/sdksandbox" + +#define EXPAND_MNT_PATH "/mnt/expand/\?\?\?\?\?\?\?\?-\?\?\?\?-\?\?\?\?-\?\?\?\?-\?\?\?\?\?\?\?\?\?\?\?\?" +#define EXPAND_USER_PATH EXPAND_MNT_PATH "/user" +#define EXPAND_USER_DE_PATH EXPAND_MNT_PATH "/user_de" +#define EXPAND_SDK_CE_PATH EXPAND_MNT_PATH "/misc_ce/*/sdksandbox" +#define EXPAND_SDK_DE_PATH EXPAND_MNT_PATH "/misc_de/*/sdksandbox" + +#define DATA_DATA_PREFIX DATA_DATA_PATH "/" +#define DATA_USER_PREFIX DATA_USER_PATH "/" +#define DATA_USER_DE_PREFIX DATA_USER_DE_PATH "/" +#define DATA_STORAGE_AREA_PREFIX DATA_STORAGE_AREA_PATH "/" +#define DATA_MISC_CE_PREFIX DATA_MISC_CE_PATH "/" +#define DATA_MISC_DE_PREFIX DATA_MISC_DE_PATH "/" +#define EXPAND_MNT_PATH_PREFIX EXPAND_MNT_PATH "/" + +bool is_app_data_path(const char *pathname) { + int flags = FNM_LEADING_DIR|FNM_PATHNAME; +#ifdef SELINUX_FLAGS_DATA_DATA_IGNORE + if (!strcmp(pathname, DATA_DATA_PATH)) { + return true; + } +#endif + return (!strncmp(pathname, DATA_DATA_PREFIX, sizeof(DATA_DATA_PREFIX)-1) || + !strncmp(pathname, DATA_USER_PREFIX, sizeof(DATA_USER_PREFIX)-1) || + !strncmp(pathname, DATA_USER_DE_PREFIX, sizeof(DATA_USER_DE_PREFIX)-1) || + !strncmp(pathname, DATA_STORAGE_AREA_PREFIX, sizeof(DATA_STORAGE_AREA_PREFIX)-1) || + !fnmatch(EXPAND_USER_PATH, pathname, flags) || + !fnmatch(EXPAND_USER_DE_PATH, pathname, flags) || + !fnmatch(SDK_SANDBOX_DATA_CE_PATH, pathname, flags) || + !fnmatch(SDK_SANDBOX_DATA_DE_PATH, pathname, flags) || + !fnmatch(EXPAND_SDK_CE_PATH, pathname, flags) || + !fnmatch(EXPAND_SDK_DE_PATH, pathname, flags)); +} + +/* + * Extract the userid from a path. + * On success, pathname is updated past the userid. + * Returns 0 on success, -1 on error + */ +static int extract_userid(const char **pathname, unsigned int *userid) +{ + char *end = NULL; + + errno = 0; + *userid = strtoul(*pathname, &end, 10); + if (errno) { + selinux_log(SELINUX_ERROR, "SELinux: Could not parse userid %s: %s.\n", + *pathname, strerror(errno)); + return -1; + } + if (*pathname == end) { + return -1; + } + if (*userid > 1000) { + return -1; + } + *pathname = end; + return 0; +} + +int extract_pkgname_and_userid(const char *pathname, char **pkgname, unsigned int *userid) +{ + char *end = NULL; + + if (pkgname == NULL || *pkgname != NULL || userid == NULL) { + errno = EINVAL; + return -2; + } + + /* Skip directory prefix before package name. */ + if (!strncmp(pathname, DATA_DATA_PREFIX, sizeof(DATA_DATA_PREFIX)-1)) { + pathname += sizeof(DATA_DATA_PREFIX) - 1; + } else if (!strncmp(pathname, DATA_USER_PREFIX, sizeof(DATA_USER_PREFIX)-1)) { + pathname += sizeof(DATA_USER_PREFIX) - 1; + int rc = extract_userid(&pathname, userid); + if (rc) + return -1; + if (*pathname == '/') + pathname++; + else + return -1; + } else if (!strncmp(pathname, DATA_USER_DE_PREFIX, sizeof(DATA_USER_DE_PREFIX)-1)) { + pathname += sizeof(DATA_USER_DE_PREFIX) - 1; + int rc = extract_userid(&pathname, userid); + if (rc) + return -1; + if (*pathname == '/') + pathname++; + else + return -1; + } else if (!strncmp(pathname, DATA_STORAGE_AREA_PREFIX, sizeof(DATA_STORAGE_AREA_PREFIX)-1)) { + pathname += sizeof(DATA_STORAGE_AREA_PREFIX) - 1; + int rc = extract_userid(&pathname, userid); + if (rc) + return -1; + if (*pathname == '/') + pathname++; + else + return -1; + } else if (!fnmatch(EXPAND_USER_PATH, pathname, FNM_LEADING_DIR|FNM_PATHNAME)) { + pathname += sizeof(EXPAND_USER_PATH); + int rc = extract_userid(&pathname, userid); + if (rc) + return -1; + if (*pathname == '/') + pathname++; + else + return -1; + } else if (!fnmatch(EXPAND_USER_DE_PATH, pathname, FNM_LEADING_DIR|FNM_PATHNAME)) { + pathname += sizeof(EXPAND_USER_DE_PATH); + int rc = extract_userid(&pathname, userid); + if (rc) + return -1; + if (*pathname == '/') + pathname++; + else + return -1; + } else if (!strncmp(pathname, DATA_MISC_CE_PREFIX, sizeof(DATA_MISC_CE_PREFIX)-1)) { + pathname += sizeof(DATA_MISC_CE_PREFIX) - 1; + int rc = extract_userid(&pathname, userid); + if (rc) + return -1; + if (!strncmp(pathname, "/sdksandbox/", sizeof("/sdksandbox/")-1)) + pathname += sizeof("/sdksandbox/") - 1; + else + return -1; + } else if (!strncmp(pathname, DATA_MISC_DE_PREFIX, sizeof(DATA_MISC_DE_PREFIX)-1)) { + pathname += sizeof(DATA_MISC_DE_PREFIX) - 1; + int rc = extract_userid(&pathname, userid); + if (rc) + return -1; + if (!strncmp(pathname, "/sdksandbox/", sizeof("/sdksandbox/")-1)) + pathname += sizeof("/sdksandbox/") - 1; + else + return -1; + } else if (!fnmatch(EXPAND_SDK_CE_PATH, pathname, FNM_LEADING_DIR|FNM_PATHNAME)) { + pathname += sizeof(EXPAND_MNT_PATH_PREFIX) - 1; + pathname += sizeof("misc_ce/") - 1; + int rc = extract_userid(&pathname, userid); + if (rc) + return -1; + if (!strncmp(pathname, "/sdksandbox/", sizeof("/sdksandbox/")-1)) + pathname += sizeof("/sdksandbox/") - 1; + else + return -1; + } else if (!fnmatch(EXPAND_SDK_DE_PATH, pathname, FNM_LEADING_DIR|FNM_PATHNAME)) { + pathname += sizeof(EXPAND_MNT_PATH_PREFIX) - 1; + pathname += sizeof("misc_de/") - 1; + int rc = extract_userid(&pathname, userid); + if (rc) + return -1; + if (!strncmp(pathname, "/sdksandbox/", sizeof("/sdksandbox/")-1)) + pathname += sizeof("/sdksandbox/") - 1; + else + return -1; + } else + return -1; + + if (!(*pathname)) + return -1; + + *pkgname = strdup(pathname); + if (!(*pkgname)) + return -2; + + // Trim pkgname. + for (end = *pkgname; *end && *end != '/'; end++); + *end = '\0'; + + return 0; +} + static void __selinux_log_callback(bool add_to_event_log, int type, const char *fmt, va_list ap) { int priority; char *strp; diff --git a/libselinux/src/android/android_device.c b/libselinux/src/android/android_device.c index df110739..9b2d2d87 100644 --- a/libselinux/src/android/android_device.c +++ b/libselinux/src/android/android_device.c @@ -251,196 +251,8 @@ struct pkg_info *package_info_lookup(const char *name) #define DATA_SYSTEM_CE_PATH "/data/system_ce" #define DATA_VENDOR_CE_PATH "/data/vendor_ce" #define DATA_MISC_CE_PATH "/data/misc_ce" -#define DATA_MISC_DE_PATH "/data/misc_de" -/* The path prefixes of package data directories. */ -#define DATA_DATA_PATH "/data/data" -#define DATA_USER_PATH "/data/user" -#define DATA_USER_DE_PATH "/data/user_de" -#define DATA_STORAGE_AREA_PATH "/data/storage_area" #define USER_PROFILE_PATH "/data/misc/profiles/cur/*" -#define SDK_SANDBOX_DATA_CE_PATH "/data/misc_ce/*/sdksandbox" -#define SDK_SANDBOX_DATA_DE_PATH "/data/misc_de/*/sdksandbox" - -#define EXPAND_MNT_PATH "/mnt/expand/\?\?\?\?\?\?\?\?-\?\?\?\?-\?\?\?\?-\?\?\?\?-\?\?\?\?\?\?\?\?\?\?\?\?" -#define EXPAND_USER_PATH EXPAND_MNT_PATH "/user" -#define EXPAND_USER_DE_PATH EXPAND_MNT_PATH "/user_de" -#define EXPAND_SDK_CE_PATH EXPAND_MNT_PATH "/misc_ce/*/sdksandbox" -#define EXPAND_SDK_DE_PATH EXPAND_MNT_PATH "/misc_de/*/sdksandbox" - -#define DATA_DATA_PREFIX DATA_DATA_PATH "/" -#define DATA_USER_PREFIX DATA_USER_PATH "/" -#define DATA_USER_DE_PREFIX DATA_USER_DE_PATH "/" -#define DATA_STORAGE_AREA_PREFIX DATA_STORAGE_AREA_PATH "/" -#define DATA_MISC_CE_PREFIX DATA_MISC_CE_PATH "/" -#define DATA_MISC_DE_PREFIX DATA_MISC_DE_PATH "/" -#define EXPAND_MNT_PATH_PREFIX EXPAND_MNT_PATH "/" - -/* - * This method helps in identifying paths that refer to users' app data. Labeling for app data is - * based on seapp_contexts and seinfo assignments rather than file_contexts and is managed by - * installd rather than by init. - */ -static bool is_app_data_path(const char *pathname) { - int flags = FNM_LEADING_DIR|FNM_PATHNAME; -#ifdef SELINUX_FLAGS_DATA_DATA_IGNORE - if (!strcmp(pathname, DATA_DATA_PATH)) { - return true; - } -#endif - return (!strncmp(pathname, DATA_DATA_PREFIX, sizeof(DATA_DATA_PREFIX)-1) || - !strncmp(pathname, DATA_USER_PREFIX, sizeof(DATA_USER_PREFIX)-1) || - !strncmp(pathname, DATA_USER_DE_PREFIX, sizeof(DATA_USER_DE_PREFIX)-1) || - !strncmp(pathname, DATA_STORAGE_AREA_PREFIX, sizeof(DATA_STORAGE_AREA_PREFIX)-1) || - !fnmatch(EXPAND_USER_PATH, pathname, flags) || - !fnmatch(EXPAND_USER_DE_PATH, pathname, flags) || - !fnmatch(SDK_SANDBOX_DATA_CE_PATH, pathname, flags) || - !fnmatch(SDK_SANDBOX_DATA_DE_PATH, pathname, flags) || - !fnmatch(EXPAND_SDK_CE_PATH, pathname, flags) || - !fnmatch(EXPAND_SDK_DE_PATH, pathname, flags)); -} - -/* - * Extract the userid from a path. - * On success, pathname is updated past the userid. - * Returns 0 on success, -1 on error - */ -static int extract_userid(const char **pathname, unsigned int *userid) -{ - char *end = NULL; - - errno = 0; - *userid = strtoul(*pathname, &end, 10); - if (errno) { - selinux_log(SELINUX_ERROR, "SELinux: Could not parse userid %s: %s.\n", - *pathname, strerror(errno)); - return -1; - } - if (*pathname == end) { - return -1; - } - if (*userid > 1000) { - return -1; - } - *pathname = end; - return 0; -} - -/* Extract the pkgname and userid from a path. - * On success, the caller is responsible for free'ing pkgname. - * Returns 0 on success, -1 on invalid path, -2 on error. - */ -static int extract_pkgname_and_userid(const char *pathname, char **pkgname, unsigned int *userid) -{ - char *end = NULL; - - if (pkgname == NULL || *pkgname != NULL || userid == NULL) { - errno = EINVAL; - return -2; - } - - /* Skip directory prefix before package name. */ - if (!strncmp(pathname, DATA_DATA_PREFIX, sizeof(DATA_DATA_PREFIX)-1)) { - pathname += sizeof(DATA_DATA_PREFIX) - 1; - } else if (!strncmp(pathname, DATA_USER_PREFIX, sizeof(DATA_USER_PREFIX)-1)) { - pathname += sizeof(DATA_USER_PREFIX) - 1; - int rc = extract_userid(&pathname, userid); - if (rc) - return -1; - if (*pathname == '/') - pathname++; - else - return -1; - } else if (!strncmp(pathname, DATA_USER_DE_PREFIX, sizeof(DATA_USER_DE_PREFIX)-1)) { - pathname += sizeof(DATA_USER_DE_PREFIX) - 1; - int rc = extract_userid(&pathname, userid); - if (rc) - return -1; - if (*pathname == '/') - pathname++; - else - return -1; - } else if (!strncmp(pathname, DATA_STORAGE_AREA_PREFIX, sizeof(DATA_STORAGE_AREA_PREFIX)-1)) { - pathname += sizeof(DATA_STORAGE_AREA_PREFIX) - 1; - int rc = extract_userid(&pathname, userid); - if (rc) - return -1; - if (*pathname == '/') - pathname++; - else - return -1; - } else if (!fnmatch(EXPAND_USER_PATH, pathname, FNM_LEADING_DIR|FNM_PATHNAME)) { - pathname += sizeof(EXPAND_USER_PATH); - int rc = extract_userid(&pathname, userid); - if (rc) - return -1; - if (*pathname == '/') - pathname++; - else - return -1; - } else if (!fnmatch(EXPAND_USER_DE_PATH, pathname, FNM_LEADING_DIR|FNM_PATHNAME)) { - pathname += sizeof(EXPAND_USER_DE_PATH); - int rc = extract_userid(&pathname, userid); - if (rc) - return -1; - if (*pathname == '/') - pathname++; - else - return -1; - } else if (!strncmp(pathname, DATA_MISC_CE_PREFIX, sizeof(DATA_MISC_CE_PREFIX)-1)) { - pathname += sizeof(DATA_MISC_CE_PREFIX) - 1; - int rc = extract_userid(&pathname, userid); - if (rc) - return -1; - if (!strncmp(pathname, "/sdksandbox/", sizeof("/sdksandbox/")-1)) - pathname += sizeof("/sdksandbox/") - 1; - else - return -1; - } else if (!strncmp(pathname, DATA_MISC_DE_PREFIX, sizeof(DATA_MISC_DE_PREFIX)-1)) { - pathname += sizeof(DATA_MISC_DE_PREFIX) - 1; - int rc = extract_userid(&pathname, userid); - if (rc) - return -1; - if (!strncmp(pathname, "/sdksandbox/", sizeof("/sdksandbox/")-1)) - pathname += sizeof("/sdksandbox/") - 1; - else - return -1; - } else if (!fnmatch(EXPAND_SDK_CE_PATH, pathname, FNM_LEADING_DIR|FNM_PATHNAME)) { - pathname += sizeof(EXPAND_MNT_PATH_PREFIX) - 1; - pathname += sizeof("misc_ce/") - 1; - int rc = extract_userid(&pathname, userid); - if (rc) - return -1; - if (!strncmp(pathname, "/sdksandbox/", sizeof("/sdksandbox/")-1)) - pathname += sizeof("/sdksandbox/") - 1; - else - return -1; - } else if (!fnmatch(EXPAND_SDK_DE_PATH, pathname, FNM_LEADING_DIR|FNM_PATHNAME)) { - pathname += sizeof(EXPAND_MNT_PATH_PREFIX) - 1; - pathname += sizeof("misc_de/") - 1; - int rc = extract_userid(&pathname, userid); - if (rc) - return -1; - if (!strncmp(pathname, "/sdksandbox/", sizeof("/sdksandbox/")-1)) - pathname += sizeof("/sdksandbox/") - 1; - else - return -1; - } else - return -1; - - if (!(*pathname)) - return -1; - - *pkgname = strdup(pathname); - if (!(*pkgname)) - return -2; - - // Trim pkgname. - for (end = *pkgname; *end && *end != '/'; end++); - *end = '\0'; - - return 0; -} static int pkgdir_selabel_lookup(const char *pathname, const char *seinfo, diff --git a/libselinux/src/android/android_internal.h b/libselinux/src/android/android_internal.h index e5d69402..d3adebf1 100644 --- a/libselinux/src/android/android_internal.h +++ b/libselinux/src/android/android_internal.h @@ -55,6 +55,19 @@ struct selabel_handle* context_handle( const path_alts_t *context_paths, const char* name); +/* + * This method helps in identifying paths that refer to users' app data. + * Labeling for app data is based on seapp_contexts and seinfo assignments + * rather than file_contexts and is managed by installd rather than by init. + */ +bool is_app_data_path(const char *pathname); + +/* Extract the pkgname and userid from a path. + * On success, the caller is responsible for free'ing pkgname. + * Returns 0 on success, -1 on invalid path, -2 on error. + */ +int extract_pkgname_and_userid(const char *pathname, char **pkgname, unsigned int *userid); + /* The kind of request when looking up an seapp_context. */ enum seapp_kind { /* Returns the SELinux type for the app data directory */ |