diff options
Diffstat (limited to 'run-as')
-rw-r--r-- | run-as/Android.mk | 2 | ||||
-rw-r--r-- | run-as/package.c | 44 | ||||
-rw-r--r-- | run-as/package.h | 1 | ||||
-rw-r--r-- | run-as/run-as.c | 6 |
4 files changed, 48 insertions, 5 deletions
diff --git a/run-as/Android.mk b/run-as/Android.mk index 043cc3a..a8f2885 100644 --- a/run-as/Android.mk +++ b/run-as/Android.mk @@ -3,6 +3,8 @@ include $(CLEAR_VARS) LOCAL_SRC_FILES:= run-as.c package.c +LOCAL_SHARED_LIBRARIES := libselinux + LOCAL_MODULE:= run-as include $(BUILD_EXECUTABLE) diff --git a/run-as/package.c b/run-as/package.c index 143d647..27fc1eb 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. @@ -76,13 +80,30 @@ map_file(const char* filename, size_t* filesize) struct stat st; size_t length = 0; void* address = NULL; + gid_t oldegid; *filesize = 0; + /* + * Temporarily switch effective GID to allow us to read + * the packages file + */ + + oldegid = getegid(); + if (setegid(AID_SYSTEM) < 0) { + return NULL; + } + /* open the file for reading */ fd = TEMP_FAILURE_RETRY(open(filename, O_RDONLY)); - if (fd < 0) + if (fd < 0) { return NULL; + } + + /* restore back to our old egid */ + if (setegid(oldegid) < 0) { + goto EXIT; + } /* get its size */ ret = TEMP_FAILURE_RETRY(fstat(fd, &st)); @@ -411,6 +432,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 +443,14 @@ get_package_info(const char* pkgName, PackageInfo *info) /* expect the following format on each line of the control file: * - * <pkgName> <uid> <debugFlag> <dataDir> + * <pkgName> <uid> <debugFlag> <dataDir> <seinfo> * * where: * <pkgName> is the package's name * <uid> is the application-specific user Id (decimal) * <debugFlag> is 1 if the package is debuggable, or 0 otherwise * <dataDir> is the path to the package's data directory (e.g. /data/data/com.example.foo) + * <seinfo> is the seinfo label associated with the package * * The file is generated in com.android.server.PackageManagerService.Settings.writeLP() */ @@ -483,7 +506,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 852af06..34603c0 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 20e1530..3c0ecc4 100644 --- a/run-as/run-as.c +++ b/run-as/run-as.c @@ -29,6 +29,7 @@ #include <time.h> #include <stdarg.h> +#include <selinux/android.h> #include <private/android_filesystem_config.h> #include "package.h" @@ -162,6 +163,11 @@ int main(int argc, char **argv) return 1; } + if (selinux_android_setcontext(uid, 0, info.seinfo, pkgname) < 0) { + panic("Could not set SELinux security context: %s\n", strerror(errno)); + return 1; + } + /* User specified command for exec. */ if (argc >= 3 ) { if (execvp(argv[2], argv+2) < 0) { |