From fced3ded831cb084121b10a78c12de99c89004aa Mon Sep 17 00:00:00 2001 From: Robert Craig Date: Tue, 26 Mar 2013 08:09:09 -0400 Subject: [PATCH] run-as: Get seinfo from packages.list and pass to libselinux. Change allows the proper seinfo value to be passed to libselinux to switch to the proper app security context before running the shell. Change-Id: I9d7ea47c920b1bc09a19008345ed7fd0aa426e87 Signed-off-by: rpcraig --- run-as/package.c | 25 +++++++++++++++++++++---- run-as/package.h | 1 + run-as/run-as.c | 2 +- 3 files changed, 23 insertions(+), 5 deletions(-) diff --git a/run-as/package.c b/run-as/package.c index 143d647bf..dce132e6a 100644 --- a/run-as/package.c +++ b/run-as/package.c @@ -47,15 +47,18 @@ /* Copy 'srclen' string bytes from 'src' into buffer 'dst' of size 'dstlen' * This function always zero-terminate the destination buffer unless * 'dstlen' is 0, even in case of overflow. + * Returns a pointer into the src string, leaving off where the copy + * has stopped. The copy will stop when dstlen, srclen or a null + * character on src has been reached. */ -static void +static const char* string_copy(char* dst, size_t dstlen, const char* src, size_t srclen) { const char* srcend = src + srclen; const char* dstend = dst + dstlen; if (dstlen == 0) - return; + return src; dstend--; /* make room for terminating zero */ @@ -63,6 +66,7 @@ string_copy(char* dst, size_t dstlen, const char* src, size_t srclen) *dst++ = *src++; *dst = '\0'; /* zero-terminate result */ + return src; } /* Open 'filename' and map it into our address-space. @@ -411,6 +415,7 @@ get_package_info(const char* pkgName, PackageInfo *info) info->uid = 0; info->isDebuggable = 0; info->dataDir[0] = '\0'; + info->seinfo[0] = '\0'; buffer = map_file(PACKAGES_LIST_FILE, &buffer_len); if (buffer == NULL) @@ -421,13 +426,14 @@ get_package_info(const char* pkgName, PackageInfo *info) /* expect the following format on each line of the control file: * - * + * * * where: * is the package's name * is the application-specific user Id (decimal) * is 1 if the package is debuggable, or 0 otherwise * is the path to the package's data directory (e.g. /data/data/com.example.foo) + * is the seinfo label associated with the package * * The file is generated in com.android.server.PackageManagerService.Settings.writeLP() */ @@ -483,7 +489,18 @@ get_package_info(const char* pkgName, PackageInfo *info) if (q == p) goto BAD_FORMAT; - string_copy(info->dataDir, sizeof info->dataDir, p, q - p); + p = string_copy(info->dataDir, sizeof info->dataDir, p, q - p); + + /* skip spaces */ + if (parse_spaces(&p, end) < 0) + goto BAD_FORMAT; + + /* fifth field is the seinfo string */ + q = skip_non_spaces(p, end); + if (q == p) + goto BAD_FORMAT; + + string_copy(info->seinfo, sizeof info->seinfo, p, q - p); /* Ignore the rest */ result = 0; diff --git a/run-as/package.h b/run-as/package.h index 852af0632..34603c013 100644 --- a/run-as/package.h +++ b/run-as/package.h @@ -30,6 +30,7 @@ typedef struct { uid_t uid; char isDebuggable; char dataDir[PATH_MAX]; + char seinfo[PATH_MAX]; } PackageInfo; /* see documentation in package.c for these functiosn */ diff --git a/run-as/run-as.c b/run-as/run-as.c index 9eb09aed3..3c0ecc4a9 100644 --- a/run-as/run-as.c +++ b/run-as/run-as.c @@ -163,7 +163,7 @@ int main(int argc, char **argv) return 1; } - if (selinux_android_setcontext(uid, 0, NULL, pkgname) < 0) { + if (selinux_android_setcontext(uid, 0, info.seinfo, pkgname) < 0) { panic("Could not set SELinux security context: %s\n", strerror(errno)); return 1; }