Merge "installd: reduce privileges." into jb-mr1-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
0116136f4c
@@ -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) {
|
||||
|
||||
@@ -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));
|
||||
|
||||
Reference in New Issue
Block a user