summaryrefslogtreecommitdiffstats
path: root/cmds
diff options
context:
space:
mode:
authorNick Kralevich <nnk@google.com>2012-09-04 16:29:28 -0700
committerAndroid (Google) Code Review <android-gerrit@google.com>2012-09-04 16:29:28 -0700
commit0116136f4ca252c31a96a055eea4be8a52b32f3b (patch)
tree00ea5a7be96d6286323db96ffa605ebf6a71bf5d /cmds
parent2ecaedd96cdcd0c83afa042cb8ff8e4358afa3cf (diff)
parent812b19a425b8304ac9e5408cc8ceb9f363c72559 (diff)
downloadframeworks_base-0116136f4ca252c31a96a055eea4be8a52b32f3b.zip
frameworks_base-0116136f4ca252c31a96a055eea4be8a52b32f3b.tar.gz
frameworks_base-0116136f4ca252c31a96a055eea4be8a52b32f3b.tar.bz2
Merge "installd: reduce privileges." into jb-mr1-dev
Diffstat (limited to 'cmds')
-rw-r--r--cmds/installd/commands.c23
-rw-r--r--cmds/installd/installd.c46
2 files changed, 63 insertions, 6 deletions
diff --git a/cmds/installd/commands.c b/cmds/installd/commands.c
index ab64747..9e83a67 100644
--- a/cmds/installd/commands.c
+++ b/cmds/installd/commands.c
@@ -14,6 +14,7 @@
** limitations under the License.
*/
+#include <linux/capability.h>
#include "installd.h"
#include <diskusage/dirsize.h>
@@ -665,16 +666,16 @@ int dexopt(const char *apk_path, uid_t uid, int is_public)
ALOGE("dexopt cannot open '%s' for output\n", dex_path);
goto fail;
}
- if (fchown(odex_fd, AID_SYSTEM, uid) < 0) {
- ALOGE("dexopt cannot chown '%s'\n", dex_path);
- goto fail;
- }
if (fchmod(odex_fd,
S_IRUSR|S_IWUSR|S_IRGRP |
(is_public ? S_IROTH : 0)) < 0) {
ALOGE("dexopt cannot chmod '%s'\n", dex_path);
goto fail;
}
+ if (fchown(odex_fd, AID_SYSTEM, uid) < 0) {
+ ALOGE("dexopt cannot chown '%s'\n", dex_path);
+ goto fail;
+ }
ALOGV("DexInv: --- BEGIN '%s' ---\n", apk_path);
@@ -690,13 +691,23 @@ int dexopt(const char *apk_path, uid_t uid, int is_public)
ALOGE("setuid(%d) during dexopt\n", uid);
exit(65);
}
+ // drop capabilities
+ struct __user_cap_header_struct capheader;
+ struct __user_cap_data_struct capdata[2];
+ memset(&capheader, 0, sizeof(capheader));
+ memset(&capdata, 0, sizeof(capdata));
+ capheader.version = _LINUX_CAPABILITY_VERSION_3;
+ if (capset(&capheader, &capdata[0]) < 0) {
+ ALOGE("capset failed: %s\n", strerror(errno));
+ exit(66);
+ }
if (flock(odex_fd, LOCK_EX | LOCK_NB) != 0) {
ALOGE("flock(%s) failed: %s\n", dex_path, strerror(errno));
- exit(66);
+ exit(67);
}
run_dexopt(zip_fd, odex_fd, apk_path, dexopt_flags);
- exit(67); /* only get here on exec failure */
+ exit(68); /* only get here on exec failure */
} else {
res = wait_dexopt(pid, apk_path);
if (res != 0) {
diff --git a/cmds/installd/installd.c b/cmds/installd/installd.c
index d559639..652543fd 100644
--- a/cmds/installd/installd.c
+++ b/cmds/installd/installd.c
@@ -14,6 +14,9 @@
** limitations under the License.
*/
+#include <linux/capability.h>
+#include <linux/prctl.h>
+
#include "installd.h"
@@ -491,12 +494,53 @@ fail:
return res;
}
+static void drop_privileges() {
+ if (prctl(PR_SET_KEEPCAPS, 1) < 0) {
+ ALOGE("prctl(PR_SET_KEEPCAPS) failed: %s\n", strerror(errno));
+ exit(1);
+ }
+
+ if (setgid(AID_INSTALL) < 0) {
+ ALOGE("setgid() can't drop privileges; exiting.\n");
+ exit(1);
+ }
+
+ if (setuid(AID_INSTALL) < 0) {
+ ALOGE("setuid() can't drop privileges; exiting.\n");
+ exit(1);
+ }
+
+ struct __user_cap_header_struct capheader;
+ struct __user_cap_data_struct capdata[2];
+ memset(&capheader, 0, sizeof(capheader));
+ memset(&capdata, 0, sizeof(capdata));
+ capheader.version = _LINUX_CAPABILITY_VERSION_3;
+ capheader.pid = 0;
+
+ capdata[CAP_TO_INDEX(CAP_DAC_OVERRIDE)].permitted |= CAP_TO_MASK(CAP_DAC_OVERRIDE);
+ capdata[CAP_TO_INDEX(CAP_CHOWN)].permitted |= CAP_TO_MASK(CAP_CHOWN);
+ capdata[CAP_TO_INDEX(CAP_SETUID)].permitted |= CAP_TO_MASK(CAP_SETUID);
+ capdata[CAP_TO_INDEX(CAP_SETGID)].permitted |= CAP_TO_MASK(CAP_SETGID);
+
+ capdata[0].effective = capdata[0].permitted;
+ capdata[1].effective = capdata[1].permitted;
+ capdata[0].inheritable = 0;
+ capdata[1].inheritable = 0;
+
+ if (capset(&capheader, &capdata[0]) < 0) {
+ ALOGE("capset failed: %s\n", strerror(errno));
+ exit(1);
+ }
+}
+
int main(const int argc, const char *argv[]) {
char buf[BUFFER_MAX];
struct sockaddr addr;
socklen_t alen;
int lsocket, s, count;
+ ALOGI("installd firing up\n");
+
if (initialize_globals() < 0) {
ALOGE("Could not initialize globals; exiting.\n");
exit(1);
@@ -507,6 +551,8 @@ int main(const int argc, const char *argv[]) {
exit(1);
}
+ drop_privileges();
+
lsocket = android_get_control_socket(SOCKET_PATH);
if (lsocket < 0) {
ALOGE("Failed to get socket from environment: %s\n", strerror(errno));