summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOleksiy Vyalov <ovyalov@google.com>2015-06-03 16:56:29 -0700
committerOleksiy Vyalov <ovyalov@google.com>2015-06-10 12:09:10 -0700
commita08d313bb87279d2a203cded92669638e3458f5f (patch)
tree8449156fdb4cb140fc954b7bf35b3bbd7c9e94e6
parent4d7f052afbaf79c7324a2e9dd51168990b062647 (diff)
downloadcore-a08d313bb87279d2a203cded92669638e3458f5f.tar.gz
core-a08d313bb87279d2a203cded92669638e3458f5f.tar.bz2
core-a08d313bb87279d2a203cded92669638e3458f5f.zip
Extend run-as with optional --user argument.
1. Calculate AID for spawned process as (100000 * $user) + uid_from_packages.list 2. Use /data/user/$user/$packageDir as a root of a new process if $user != 0. Change-Id: I761dfb481114bd51e5a950307fcaf403e96eef10 (cherry picked from commit da31778f3b422d9583f334273eb8d9f6aabd5d34)
-rw-r--r--run-as/package.c18
-rw-r--r--run-as/package.h6
-rw-r--r--run-as/run-as.c37
3 files changed, 48 insertions, 13 deletions
diff --git a/run-as/package.c b/run-as/package.c
index 9e1f5bb22..aea89e56b 100644
--- a/run-as/package.c
+++ b/run-as/package.c
@@ -16,6 +16,7 @@
*/
#include <errno.h>
#include <fcntl.h>
+#include <stdio.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/stat.h>
@@ -421,7 +422,7 @@ parse_positive_decimal(const char** pp, const char* end)
* If the package database is corrupted, return -1 and set errno to EINVAL
*/
int
-get_package_info(const char* pkgName, PackageInfo *info)
+get_package_info(const char* pkgName, uid_t userId, PackageInfo *info)
{
char* buffer;
size_t buffer_len;
@@ -506,7 +507,20 @@ get_package_info(const char* pkgName, PackageInfo *info)
if (q == p)
goto BAD_FORMAT;
- p = string_copy(info->dataDir, sizeof info->dataDir, p, q - p);
+ /* If userId == 0 (i.e. user is device owner) we can use dataDir value
+ * from packages.list, otherwise compose data directory as
+ * /data/user/$uid/$packageId
+ */
+ if (userId == 0) {
+ p = string_copy(info->dataDir, sizeof info->dataDir, p, q - p);
+ } else {
+ snprintf(info->dataDir,
+ sizeof info->dataDir,
+ "/data/user/%d/%s",
+ userId,
+ pkgName);
+ p = q;
+ }
/* skip spaces */
if (parse_spaces(&p, end) < 0)
diff --git a/run-as/package.h b/run-as/package.h
index 34603c013..eeb59137d 100644
--- a/run-as/package.h
+++ b/run-as/package.h
@@ -33,9 +33,11 @@ typedef struct {
char seinfo[PATH_MAX];
} PackageInfo;
-/* see documentation in package.c for these functiosn */
+/* see documentation in package.c for these functions */
-extern int get_package_info(const char* packageName, PackageInfo* info);
+extern int get_package_info(const char* packageName,
+ uid_t userId,
+ PackageInfo* info);
extern int check_data_path(const char* dataDir, uid_t uid);
diff --git a/run-as/run-as.c b/run-as/run-as.c
index 368b8f1e6..3f32e7d74 100644
--- a/run-as/run-as.c
+++ b/run-as/run-as.c
@@ -102,13 +102,14 @@ panic(const char* format, ...)
static void
usage(void)
{
- panic("Usage:\n " PROGNAME " <package-name> <command> [<args>]\n");
+ panic("Usage:\n " PROGNAME " <package-name> [--user <uid>] <command> [<args>]\n");
}
int main(int argc, char **argv)
{
const char* pkgname;
- int myuid, uid, gid;
+ uid_t myuid, uid, gid, userAppId = 0;
+ int commandArgvOfs = 2, userId = 0;
PackageInfo info;
struct __user_cap_header_struct capheader;
struct __user_cap_data_struct capdata[2];
@@ -136,14 +137,31 @@ int main(int argc, char **argv)
panic("Could not set capabilities: %s\n", strerror(errno));
}
- /* retrieve package information from system (does setegid) */
pkgname = argv[1];
- if (get_package_info(pkgname, &info) < 0) {
+
+ /* get user_id from command line if provided */
+ if ((argc >= 4) && !strcmp(argv[2], "--user")) {
+ userId = atoi(argv[3]);
+ if (userId < 0)
+ panic("Negative user id %d is provided\n", userId);
+ commandArgvOfs += 2;
+ }
+
+ /* retrieve package information from system (does setegid) */
+ if (get_package_info(pkgname, userId, &info) < 0) {
panic("Package '%s' is unknown\n", pkgname);
}
+ /* verify that user id is not too big. */
+ if ((UID_MAX - info.uid) / AID_USER < (uid_t)userId) {
+ panic("User id %d is too big\n", userId);
+ }
+
+ /* calculate user app ID. */
+ userAppId = (AID_USER * userId) + info.uid;
+
/* reject system packages */
- if (info.uid < AID_APP) {
+ if (userAppId < AID_APP) {
panic("Package '%s' is not an application\n", pkgname);
}
@@ -153,14 +171,14 @@ int main(int argc, char **argv)
}
/* check that the data directory path is valid */
- if (check_data_path(info.dataDir, info.uid) < 0) {
+ if (check_data_path(info.dataDir, userAppId) < 0) {
panic("Package '%s' has corrupt installation\n", pkgname);
}
/* Ensure that we change all real/effective/saved IDs at the
* same time to avoid nasty surprises.
*/
- uid = gid = info.uid;
+ uid = gid = userAppId;
if(setresgid(gid,gid,gid) || setresuid(uid,uid,uid)) {
panic("Permission denied\n");
}
@@ -181,8 +199,9 @@ int main(int argc, char **argv)
}
/* User specified command for exec. */
- if ((argc >= 3) && (execvp(argv[2], argv+2) < 0)) {
- panic("exec failed for %s: %s\n", argv[2], strerror(errno));
+ if ((argc >= commandArgvOfs + 1) &&
+ (execvp(argv[commandArgvOfs], argv+commandArgvOfs) < 0)) {
+ panic("exec failed for %s: %s\n", argv[commandArgvOfs], strerror(errno));
}
/* Default exec shell. */