summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndy McFadden <fadden@android.com>2010-11-08 17:05:39 -0800
committerAndy McFadden <fadden@android.com>2010-11-08 17:33:07 -0800
commit886130bc7ff992940e152636f57072e58c91aa2e (patch)
tree6ccce7d39fd44311da65d77754ac28f6f10eecc9
parentfbe515510323ee65ce594b8eda5547c1cbfb8ad9 (diff)
downloaddalvik-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.java19
-rw-r--r--vm/native/dalvik_system_Zygote.c80
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 },
};