Merge "Include userid when restoring context for /data" am: 413194a2ba am: ad8247b9b9 am: 53060d719b

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

Change-Id: Ifa40c6e6615927bd7ee0cce52c839d5d27ffd85f
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
Thiébaud Weksteen 2022-08-02 02:01:21 +00:00 committed by Automerger Merge Worker
commit dca9d67be1

View file

@ -1114,103 +1114,163 @@ static bool is_app_data_path(const char *pathname) {
!fnmatch(EXPAND_SDK_DE_PATH, pathname, flags));
}
static int pkgdir_selabel_lookup(const char *pathname,
const char *seinfo,
uid_t uid,
char **secontextp)
/*
* 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 *pkgname = NULL, *end = NULL;
struct pkg_info *info = NULL;
char *secontext = *secontextp;
context_t ctx = NULL;
int rc = 0;
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 error, -2 on invalid arguments
*/
static int extract_pkgname_and_userid(const char *pathname, char **pkgname, unsigned int *userid)
{
char *end = NULL;
if (pkgname == NULL || *pkgname != NULL || userid == NULL) {
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;
while (isdigit(*pathname))
pathname++;
int rc = extract_userid(&pathname, userid);
if (rc) {
return -1;
}
if (*pathname == '/')
pathname++;
else
return 0;
return -1;
} else if (!strncmp(pathname, DATA_USER_DE_PREFIX, sizeof(DATA_USER_DE_PREFIX)-1)) {
pathname += sizeof(DATA_USER_DE_PREFIX) - 1;
while (isdigit(*pathname))
pathname++;
int rc = extract_userid(&pathname, userid);
if (rc) {
return -1;
}
if (*pathname == '/')
pathname++;
else
return 0;
return -1;
} else if (!fnmatch(EXPAND_USER_PATH, pathname, FNM_LEADING_DIR|FNM_PATHNAME)) {
pathname += sizeof(EXPAND_USER_PATH);
while (isdigit(*pathname))
pathname++;
int rc = extract_userid(&pathname, userid);
if (rc) {
return -1;
}
if (*pathname == '/')
pathname++;
else
return 0;
return -1;
} else if (!fnmatch(EXPAND_USER_DE_PATH, pathname, FNM_LEADING_DIR|FNM_PATHNAME)) {
pathname += sizeof(EXPAND_USER_DE_PATH);
while (isdigit(*pathname))
pathname++;
int rc = extract_userid(&pathname, userid);
if (rc) {
return -1;
}
if (*pathname == '/')
pathname++;
else
return 0;
return -1;
} else if (!strncmp(pathname, DATA_MISC_CE_PREFIX, sizeof(DATA_MISC_CE_PREFIX)-1)) {
pathname += sizeof(DATA_MISC_CE_PREFIX) - 1;
while (isdigit(*pathname))
pathname++;
int rc = extract_userid(&pathname, userid);
if (rc) {
return -1;
}
if (!strncmp(pathname, "/sdksandbox/", sizeof("/sdksandbox/")-1)) {
pathname += sizeof("/sdksandbox/") - 1;
} else
return 0;
return -1;
} else if (!strncmp(pathname, DATA_MISC_DE_PREFIX, sizeof(DATA_MISC_DE_PREFIX)-1)) {
pathname += sizeof(DATA_MISC_DE_PREFIX) - 1;
while (isdigit(*pathname))
pathname++;
int rc = extract_userid(&pathname, userid);
if (rc) {
return -1;
}
if (!strncmp(pathname, "/sdksandbox/", sizeof("/sdksandbox/")-1)) {
pathname += sizeof("/sdksandbox/") - 1;
} else
return 0;
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;
while (isdigit(*pathname))
pathname++;
int rc = extract_userid(&pathname, userid);
if (rc) {
return -1;
}
if (!strncmp(pathname, "/sdksandbox/", sizeof("/sdksandbox/")-1)) {
pathname += sizeof("/sdksandbox/") - 1;
} else
return 0;
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;
while (isdigit(*pathname))
pathname++;
int rc = extract_userid(&pathname, userid);
if (rc) {
return -1;
}
if (!strncmp(pathname, "/sdksandbox/", sizeof("/sdksandbox/")-1)) {
pathname += sizeof("/sdksandbox/") - 1;
} else
return 0;
return -1;
} else
return 0;
if (!(*pathname))
return 0;
pkgname = strdup(pathname);
if (!pkgname)
return -1;
for (end = pkgname; *end && *end != '/'; end++)
;
pathname = end;
if (*end)
pathname++;
if (!(*pathname))
return -1;
*pkgname = strdup(pathname);
if (!(*pkgname))
return -1;
// Trim pkgname.
for (end = *pkgname; *end && *end != '/'; end++);
*end = '\0';
return 0;
}
static int pkgdir_selabel_lookup(const char *pathname,
const char *seinfo,
uid_t uid,
char **secontextp)
{
char *pkgname = NULL;
struct pkg_info *info = NULL;
char *secontext = *secontextp;
context_t ctx = NULL;
int rc = 0;
unsigned int userid_from_path = 0;
rc = extract_pkgname_and_userid(pathname, &pkgname, &userid_from_path);
if (rc) {
return -1;
}
if (!seinfo) {
info = package_info_lookup(pkgname);
if (!info) {
@ -1219,6 +1279,8 @@ static int pkgdir_selabel_lookup(const char *pathname,
free(pkgname);
return -1;
}
// info->uid only contains the appid and not the userid.
info->uid += userid_from_path * AID_USER_OFFSET;
}
ctx = context_new(secontext);