diff options
author | Andy McFadden <fadden@android.com> | 2010-11-08 17:05:39 -0800 |
---|---|---|
committer | Andy McFadden <fadden@android.com> | 2010-11-08 17:33:07 -0800 |
commit | 886130bc7ff992940e152636f57072e58c91aa2e (patch) | |
tree | 6ccce7d39fd44311da65d77754ac28f6f10eecc9 | |
parent | fbe515510323ee65ce594b8eda5547c1cbfb8ad9 (diff) | |
download | dalvik-886130bc7ff992940e152636f57072e58c91aa2e.tar.gz |
Two patches.
Patch 1a+1b: Set capabilities sooner.
(cherry-pick from gingerbread I22fde728bd5d65774f8fdf1fa45956fe18358c4c)
(hand-pick from gingerbread Ief58bdfff2cb82d7824ef796c2c1031f525f6ee9,
plus minor tweak to avoid altering the API)
Patch 3: If there's an error dropping privileges, abort.
(cherry-pick from gingerbread I85ce12e93cb8c297add756dc3b872b8346eda00b)
Bug 3176774
Change-Id: If8285d7bfd5a466bd77c0f7ffadf1bf96d31db06
-rw-r--r-- | libcore/dalvik/src/main/java/dalvik/system/Zygote.java | 19 | ||||
-rw-r--r-- | vm/native/dalvik_system_Zygote.c | 80 |
2 files changed, 85 insertions, 14 deletions
diff --git a/libcore/dalvik/src/main/java/dalvik/system/Zygote.java b/libcore/dalvik/src/main/java/dalvik/system/Zygote.java index 641e85616..653e4d014 100644 --- a/libcore/dalvik/src/main/java/dalvik/system/Zygote.java +++ b/libcore/dalvik/src/main/java/dalvik/system/Zygote.java @@ -109,12 +109,27 @@ public class Zygote { * dimension having a length of 3 and representing * (resource, rlim_cur, rlim_max). These are set via the posix * setrlimit(2) call. + * @param permittedCapabilities argument for setcap() + * @param effectiveCapabilities argument for setcap() * * @return 0 if this is the child, pid of the child * if this is the parent, or -1 on error. + * + * @hide + */ + native public static int forkSystemServer(int uid, int gid, + int[] gids, int debugFlags, int[][] rlimits, + long permittedCapabilities, long effectiveCapabilities); + + /* + * For bug 3176774, we needed to update forkSystemServer() after + * the API was locked down. To avoid going out of sync with the + * API description file, we provide a dummy function here. */ - native public static int forkSystemServer(int uid, int gid, - int[] gids, int debugFlags, int[][] rlimits); + public static int forkSystemServer(int uid, int gid, + int[] gids, int debugFlags, int[][] rlimits) { + throw new UnsupportedOperationException(); + } /** * Special method to start the system server process. diff --git a/vm/native/dalvik_system_Zygote.c b/vm/native/dalvik_system_Zygote.c index f8e825096..f50125580 100644 --- a/vm/native/dalvik_system_Zygote.c +++ b/vm/native/dalvik_system_Zygote.c @@ -324,10 +324,38 @@ static void enableDebugFeatures(u4 debugFlags) #endif } -/* +/* + * Set Linux capability flags. + * + * Returns 0 on success, errno on failure. + */ +static int setCapabilities(int64_t permitted, int64_t effective) +{ +#ifdef HAVE_ANDROID_OS + struct __user_cap_header_struct capheader; + struct __user_cap_data_struct capdata; + + memset(&capheader, 0, sizeof(capheader)); + memset(&capdata, 0, sizeof(capdata)); + + capheader.version = _LINUX_CAPABILITY_VERSION; + capheader.pid = 0; + + capdata.effective = effective; + capdata.permitted = permitted; + + LOGV("CAPSET perm=%llx eff=%llx\n", permitted, effective); + if (capset(&capheader, &capdata) != 0) + return errno; +#endif /*HAVE_ANDROID_OS*/ + + return 0; +} + +/* * Utility routine to fork zygote and specialize the child process. */ -static pid_t forkAndSpecializeCommon(const u4* args) +static pid_t forkAndSpecializeCommon(const u4* args, bool isSystemServer) { pid_t pid; @@ -336,6 +364,21 @@ static pid_t forkAndSpecializeCommon(const u4* args) ArrayObject* gids = (ArrayObject *)args[2]; u4 debugFlags = args[3]; ArrayObject *rlimits = (ArrayObject *)args[4]; + int64_t permittedCapabilities, effectiveCapabilities; + + if (isSystemServer) { + /* + * Don't use GET_ARG_LONG here for now. gcc is generating code + * that uses register d8 as a temporary, and that's coming out + * scrambled in the child process. b/3138621 + */ + //permittedCapabilities = GET_ARG_LONG(args, 5); + //effectiveCapabilities = GET_ARG_LONG(args, 7); + permittedCapabilities = args[5] | (int64_t) args[6] << 32; + effectiveCapabilities = args[7] | (int64_t) args[8] << 32; + } else { + permittedCapabilities = effectiveCapabilities = 0; + } if (!gDvm.zygote) { dvmThrowException("Ljava/lang/IllegalStateException;", @@ -367,7 +410,8 @@ static pid_t forkAndSpecializeCommon(const u4* args) err = prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0); if (err < 0) { - LOGW("cannot PR_SET_KEEPCAPS errno: %d", errno); + LOGE("cannot PR_SET_KEEPCAPS: %s", strerror(errno)); + dvmAbort(); } } @@ -376,23 +420,34 @@ static pid_t forkAndSpecializeCommon(const u4* args) err = setgroupsIntarray(gids); if (err < 0) { - LOGW("cannot setgroups() errno: %d", errno); + LOGE("cannot setgroups(): %s", strerror(errno)); + dvmAbort(); } err = setrlimitsFromArray(rlimits); if (err < 0) { - LOGW("cannot setrlimit() errno: %d", errno); + LOGE("cannot setrlimit(): %s", strerror(errno)); + dvmAbort(); } err = setgid(gid); if (err < 0) { - LOGW("cannot setgid(%d) errno: %d", gid, errno); + LOGE("cannot setgid(%d): %s", gid, strerror(errno)); + dvmAbort(); } err = setuid(uid); if (err < 0) { - LOGW("cannot setuid(%d) errno: %d", uid, errno); + LOGE("cannot setuid(%d): %s", uid, strerror(errno)); + dvmAbort(); + } + + err = setCapabilities(permittedCapabilities, effectiveCapabilities); + if (err != 0) { + LOGE("cannot set capabilities (%llx,%llx): %s\n", + permittedCapabilities, effectiveCapabilities, strerror(err)); + dvmAbort(); } /* @@ -425,19 +480,20 @@ static void Dalvik_dalvik_system_Zygote_forkAndSpecialize(const u4* args, { pid_t pid; - pid = forkAndSpecializeCommon(args); + pid = forkAndSpecializeCommon(args, false); RETURN_INT(pid); } -/* native public static int forkSystemServer(int uid, int gid, - * int[] gids, int debugFlags); +/* native public static int forkSystemServer(int uid, int gid, + * int[] gids, int debugFlags, long permittedCapabilities, + * long effectiveCapabilities); */ static void Dalvik_dalvik_system_Zygote_forkSystemServer( const u4* args, JValue* pResult) { pid_t pid; - pid = forkAndSpecializeCommon(args); + pid = forkAndSpecializeCommon(args, true); /* The zygote process checks whether the child process has died or not. */ if (pid > 0) { @@ -462,7 +518,7 @@ const DalvikNativeMethod dvm_dalvik_system_Zygote[] = { Dalvik_dalvik_system_Zygote_fork }, { "forkAndSpecialize", "(II[II[[I)I", Dalvik_dalvik_system_Zygote_forkAndSpecialize }, - { "forkSystemServer", "(II[II[[I)I", + { "forkSystemServer", "(II[II[[IJJ)I", Dalvik_dalvik_system_Zygote_forkSystemServer }, { NULL, NULL, NULL }, }; |