Loading cmds/installd/Android.mk +5 −1 Original line number Original line Diff line number Diff line Loading @@ -12,7 +12,10 @@ LOCAL_MODULE := libinstalld LOCAL_MODULE_TAGS := eng tests LOCAL_MODULE_TAGS := eng tests LOCAL_SRC_FILES := $(common_src_files) LOCAL_SRC_FILES := $(common_src_files) LOCAL_CFLAGS := $(common_cflags) LOCAL_CFLAGS := $(common_cflags) LOCAL_SHARED_LIBRARIES := libbase LOCAL_SHARED_LIBRARIES := \ libbase \ liblogwrap \ LOCAL_ADDITIONAL_DEPENDENCIES += $(LOCAL_PATH)/Android.mk LOCAL_ADDITIONAL_DEPENDENCIES += $(LOCAL_PATH)/Android.mk LOCAL_CLANG := true LOCAL_CLANG := true include $(BUILD_STATIC_LIBRARY) include $(BUILD_STATIC_LIBRARY) Loading @@ -30,6 +33,7 @@ LOCAL_SHARED_LIBRARIES := \ libbase \ libbase \ libcutils \ libcutils \ liblog \ liblog \ liblogwrap \ libselinux \ libselinux \ LOCAL_STATIC_LIBRARIES := libdiskusage LOCAL_STATIC_LIBRARIES := libdiskusage Loading cmds/installd/commands.cpp +86 −7 Original line number Original line Diff line number Diff line Loading @@ -16,15 +16,18 @@ #include "installd.h" #include "installd.h" #include <inttypes.h> #include <base/stringprintf.h> #include <sys/capability.h> #include <base/logging.h> #include <sys/file.h> #include <cutils/sched_policy.h> #include <cutils/sched_policy.h> #include <diskusage/dirsize.h> #include <diskusage/dirsize.h> #include <selinux/android.h> #include <logwrap/logwrap.h> #include <system/thread_defs.h> #include <system/thread_defs.h> #include <base/stringprintf.h> #include <selinux/android.h> #include <base/logging.h> #include <inttypes.h> #include <sys/capability.h> #include <sys/file.h> #include <unistd.h> using android::base::StringPrintf; using android::base::StringPrintf; Loading @@ -38,6 +41,8 @@ dir_rec_t android_media_dir; dir_rec_t android_mnt_expand_dir; dir_rec_t android_mnt_expand_dir; dir_rec_array_t android_system_dirs; dir_rec_array_t android_system_dirs; static const char* kCpPath = "/system/bin/cp"; int install(const char *uuid, const char *pkgname, uid_t uid, gid_t gid, const char *seinfo) int install(const char *uuid, const char *pkgname, uid_t uid, gid_t gid, const char *seinfo) { { if ((uid < AID_SYSTEM) || (gid < AID_SYSTEM)) { if ((uid < AID_SYSTEM) || (gid < AID_SYSTEM)) { Loading Loading @@ -172,6 +177,80 @@ int make_user_data(const char *uuid, const char *pkgname, uid_t uid, userid_t us return 0; return 0; } } int move_user_data(const char *from_uuid, const char *to_uuid, const char *package_name, appid_t appid, const char* seinfo) { std::vector<userid_t> users = get_known_users(from_uuid); // Copy package private data for all known users for (auto user : users) { std::string from(create_package_data_path(from_uuid, package_name, user)); std::string to(create_package_data_path(to_uuid, package_name, user)); std::string to_user(create_data_user_path(to_uuid, user)); // Data source may not exist for all users; that's okay if (access(from.c_str(), F_OK) != 0) { LOG(INFO) << "Missing source " << from; continue; } std::string user_path(create_data_user_path(to_uuid, user)); if (fs_prepare_dir(user_path.c_str(), 0771, AID_SYSTEM, AID_SYSTEM) != 0) { LOG(ERROR) << "Failed to prepare user target " << user_path; goto fail; } uid_t uid = multiuser_get_uid(user, appid); if (make_user_data(to_uuid, package_name, uid, user, seinfo) != 0) { LOG(ERROR) << "Failed to create package target " << to; goto fail; } char *argv[] = { (char*) kCpPath, (char*) "-F", /* delete any existing destination file first (--remove-destination) */ (char*) "-p", /* preserve timestamps, ownership, and permissions */ (char*) "-R", /* recurse into subdirectories (DEST must be a directory) */ (char*) "-P", /* Do not follow symlinks [default] */ (char*) "-d", /* don't dereference symlinks */ (char*) from.c_str(), (char*) to_user.c_str() }; LOG(DEBUG) << "Copying " << from << " to " << to; int rc = android_fork_execvp(ARRAY_SIZE(argv), argv, NULL, false, true); if (rc != 0) { LOG(ERROR) << "Failed copying " << from << " to " << to << ": status " << rc; goto fail; } if (restorecon_data(to_uuid, package_name, seinfo, uid) != 0) { LOG(ERROR) << "Failed to restorecon " << to; goto fail; } } // Copy successful, so delete old data for (auto user : users) { std::string from(create_package_data_path(from_uuid, package_name, user)); if (delete_dir_contents(from.c_str(), 1, NULL) != 0) { LOG(WARNING) << "Failed to delete " << from; } } return 0; fail: // Nuke everything we might have already copied for (auto user : users) { std::string to(create_package_data_path(to_uuid, package_name, user)); if (delete_dir_contents(to.c_str(), 1, NULL) != 0) { LOG(WARNING) << "Failed to rollback " << to; } } return -1; } int make_user_config(userid_t userid) int make_user_config(userid_t userid) { { if (ensure_config_user_dirs(userid) == -1) { if (ensure_config_user_dirs(userid) == -1) { Loading Loading @@ -1592,7 +1671,7 @@ int restorecon_data(const char* uuid, const char* pkgName, continue; continue; } } std::string pkgdir(StringPrintf("%s/%s/%s", userdir.c_str(), user, pkgName)); std::string pkgdir(StringPrintf("%s%s/%s", userdir.c_str(), user, pkgName)); if (stat(pkgdir.c_str(), &s) < 0) { if (stat(pkgdir.c_str(), &s) < 0) { continue; continue; } } Loading cmds/installd/installd.cpp +15 −46 Original line number Original line Diff line number Diff line Loading @@ -14,14 +14,15 @@ ** limitations under the License. ** limitations under the License. */ */ #include "installd.h" #include <base/logging.h> #include <sys/capability.h> #include <sys/capability.h> #include <sys/prctl.h> #include <sys/prctl.h> #include <selinux/android.h> #include <selinux/android.h> #include <selinux/avc.h> #include <selinux/avc.h> #include "installd.h" #define BUFFER_MAX 1024 /* input buffer for commands */ #define BUFFER_MAX 1024 /* input buffer for commands */ #define TOKEN_MAX 16 /* max number of arguments in buffer */ #define TOKEN_MAX 16 /* max number of arguments in buffer */ #define REPLY_MAX 256 /* largest reply allowed */ #define REPLY_MAX 256 /* largest reply allowed */ Loading Loading @@ -123,6 +124,12 @@ static int do_rm_user_data(char **arg, char reply[REPLY_MAX] __unused) return delete_user_data(parse_null(arg[0]), arg[1], atoi(arg[2])); /* uuid, pkgname, userid */ return delete_user_data(parse_null(arg[0]), arg[1], atoi(arg[2])); /* uuid, pkgname, userid */ } } static int do_mv_user_data(char **arg, char reply[REPLY_MAX] __unused) { // from_uuid, to_uuid, pkgname, appid, seinfo return move_user_data(parse_null(arg[0]), parse_null(arg[1]), arg[2], atoi(arg[3]), arg[4]); } static int do_mk_user_data(char **arg, char reply[REPLY_MAX] __unused) static int do_mk_user_data(char **arg, char reply[REPLY_MAX] __unused) { { return make_user_data(parse_null(arg[0]), arg[1], atoi(arg[2]), atoi(arg[3]), arg[4]); return make_user_data(parse_null(arg[0]), arg[1], atoi(arg[2]), atoi(arg[3]), arg[4]); Loading Loading @@ -193,6 +200,7 @@ struct cmdinfo cmds[] = { { "rmcodecache", 3, do_rm_code_cache }, { "rmcodecache", 3, do_rm_code_cache }, { "getsize", 8, do_get_size }, { "getsize", 8, do_get_size }, { "rmuserdata", 3, do_rm_user_data }, { "rmuserdata", 3, do_rm_user_data }, { "mvuserdata", 5, do_mv_user_data }, { "movefiles", 0, do_movefiles }, { "movefiles", 0, do_movefiles }, { "linklib", 4, do_linklib }, { "linklib", 4, do_linklib }, { "mkuserdata", 5, do_mk_user_data }, { "mkuserdata", 5, do_mk_user_data }, Loading Loading @@ -621,46 +629,6 @@ fail: return res; 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[CAP_TO_INDEX(CAP_FOWNER)].permitted |= CAP_TO_MASK(CAP_FOWNER); 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); } } static int log_callback(int type, const char *fmt, ...) { static int log_callback(int type, const char *fmt, ...) { va_list ap; va_list ap; int priority; int priority; Loading @@ -682,13 +650,16 @@ static int log_callback(int type, const char *fmt, ...) { return 0; return 0; } } int main(const int argc __unused, const char *argv[] __unused) { int main(const int argc __unused, char *argv[]) { char buf[BUFFER_MAX]; char buf[BUFFER_MAX]; struct sockaddr addr; struct sockaddr addr; socklen_t alen; socklen_t alen; int lsocket, s; int lsocket, s; int selinux_enabled = (is_selinux_enabled() > 0); int selinux_enabled = (is_selinux_enabled() > 0); setenv("ANDROID_LOG_TAGS", "*:v", 1); android::base::InitLogging(argv); ALOGI("installd firing up\n"); ALOGI("installd firing up\n"); union selinux_callback cb; union selinux_callback cb; Loading @@ -710,8 +681,6 @@ int main(const int argc __unused, const char *argv[] __unused) { exit(1); exit(1); } } drop_privileges(); lsocket = android_get_control_socket(SOCKET_PATH); lsocket = android_get_control_socket(SOCKET_PATH); if (lsocket < 0) { if (lsocket < 0) { ALOGE("Failed to get socket from environment: %s\n", strerror(errno)); ALOGE("Failed to get socket from environment: %s\n", strerror(errno)); Loading cmds/installd/installd.h +11 −1 Original line number Original line Diff line number Diff line Loading @@ -32,6 +32,7 @@ #include <sys/types.h> #include <sys/types.h> #include <sys/wait.h> #include <sys/wait.h> #include <string> #include <string> #include <vector> #include <cutils/fs.h> #include <cutils/fs.h> #include <cutils/sockets.h> #include <cutils/sockets.h> Loading Loading @@ -89,6 +90,8 @@ #define DEXOPT_PATCHOAT_NEEDED 2 #define DEXOPT_PATCHOAT_NEEDED 2 #define DEXOPT_SELF_PATCHOAT_NEEDED 3 #define DEXOPT_SELF_PATCHOAT_NEEDED 3 #define ARRAY_SIZE(a) (sizeof(a) / sizeof(*(a))) /* data structures */ /* data structures */ typedef struct { typedef struct { Loading Loading @@ -154,6 +157,8 @@ std::string create_data_user_path(const char* volume_uuid, userid_t userid); std::string create_data_media_path(const char* volume_uuid, userid_t userid); std::string create_data_media_path(const char* volume_uuid, userid_t userid); std::vector<userid_t> get_known_users(const char* volume_uuid); int create_user_config_path(char path[PKG_PATH_MAX], userid_t userid); int create_user_config_path(char path[PKG_PATH_MAX], userid_t userid); int create_move_path(char path[PKG_PATH_MAX], int create_move_path(char path[PKG_PATH_MAX], Loading Loading @@ -214,7 +219,10 @@ int uninstall(const char *uuid, const char *pkgname, userid_t userid); int renamepkg(const char *oldpkgname, const char *newpkgname); int renamepkg(const char *oldpkgname, const char *newpkgname); int fix_uid(const char *uuid, const char *pkgname, uid_t uid, gid_t gid); int fix_uid(const char *uuid, const char *pkgname, uid_t uid, gid_t gid); int delete_user_data(const char *uuid, const char *pkgname, userid_t userid); int delete_user_data(const char *uuid, const char *pkgname, userid_t userid); int make_user_data(const char *uuid, const char *pkgname, uid_t uid, userid_t userid, const char* seinfo); int make_user_data(const char *uuid, const char *pkgname, uid_t uid, userid_t userid, const char* seinfo); int move_user_data(const char* from_uuid, const char *to_uuid, const char *package_name, appid_t appid, const char* seinfo); int make_user_config(userid_t userid); int make_user_config(userid_t userid); int delete_user(const char *uuid, userid_t userid); int delete_user(const char *uuid, userid_t userid); int delete_cache(const char *uuid, const char *pkgname, userid_t userid); int delete_cache(const char *uuid, const char *pkgname, userid_t userid); Loading @@ -238,3 +246,5 @@ int create_oat_dir(const char* oat_dir, const char *instruction_set); int rm_package_dir(const char* apk_path); int rm_package_dir(const char* apk_path); int calculate_oat_file_path(char path[PKG_PATH_MAX], const char *oat_dir, const char *apk_path, int calculate_oat_file_path(char path[PKG_PATH_MAX], const char *oat_dir, const char *apk_path, const char *instruction_set); const char *instruction_set); int move_package_dir(char path[PKG_PATH_MAX], const char *oat_dir, const char *apk_path, const char *instruction_set); cmds/installd/utils.cpp +32 −0 Original line number Original line Diff line number Diff line Loading @@ -99,6 +99,38 @@ std::string create_data_media_path(const char* volume_uuid, userid_t userid) { return StringPrintf("%s/media/%u", create_data_path(volume_uuid).c_str(), userid); return StringPrintf("%s/media/%u", create_data_path(volume_uuid).c_str(), userid); } } std::vector<userid_t> get_known_users(const char* volume_uuid) { std::vector<userid_t> users; // We always have an owner users.push_back(0); std::string path(create_data_path(volume_uuid) + "/" + SECONDARY_USER_PREFIX); DIR* dir = opendir(path.c_str()); if (dir == NULL) { // Unable to discover other users, but at least return owner PLOG(ERROR) << "Failed to opendir " << path; return users; } struct dirent* ent; while ((ent = readdir(dir))) { if (ent->d_type != DT_DIR) { continue; } char* end; userid_t user = strtol(ent->d_name, &end, 10); if (*end == '\0' && user != 0) { LOG(DEBUG) << "Found valid user " << user; users.push_back(user); } } closedir(dir); return users; } /** /** * Create the path name for config for a certain userid. * Create the path name for config for a certain userid. * Returns 0 on success, and -1 on failure. * Returns 0 on success, and -1 on failure. Loading Loading
cmds/installd/Android.mk +5 −1 Original line number Original line Diff line number Diff line Loading @@ -12,7 +12,10 @@ LOCAL_MODULE := libinstalld LOCAL_MODULE_TAGS := eng tests LOCAL_MODULE_TAGS := eng tests LOCAL_SRC_FILES := $(common_src_files) LOCAL_SRC_FILES := $(common_src_files) LOCAL_CFLAGS := $(common_cflags) LOCAL_CFLAGS := $(common_cflags) LOCAL_SHARED_LIBRARIES := libbase LOCAL_SHARED_LIBRARIES := \ libbase \ liblogwrap \ LOCAL_ADDITIONAL_DEPENDENCIES += $(LOCAL_PATH)/Android.mk LOCAL_ADDITIONAL_DEPENDENCIES += $(LOCAL_PATH)/Android.mk LOCAL_CLANG := true LOCAL_CLANG := true include $(BUILD_STATIC_LIBRARY) include $(BUILD_STATIC_LIBRARY) Loading @@ -30,6 +33,7 @@ LOCAL_SHARED_LIBRARIES := \ libbase \ libbase \ libcutils \ libcutils \ liblog \ liblog \ liblogwrap \ libselinux \ libselinux \ LOCAL_STATIC_LIBRARIES := libdiskusage LOCAL_STATIC_LIBRARIES := libdiskusage Loading
cmds/installd/commands.cpp +86 −7 Original line number Original line Diff line number Diff line Loading @@ -16,15 +16,18 @@ #include "installd.h" #include "installd.h" #include <inttypes.h> #include <base/stringprintf.h> #include <sys/capability.h> #include <base/logging.h> #include <sys/file.h> #include <cutils/sched_policy.h> #include <cutils/sched_policy.h> #include <diskusage/dirsize.h> #include <diskusage/dirsize.h> #include <selinux/android.h> #include <logwrap/logwrap.h> #include <system/thread_defs.h> #include <system/thread_defs.h> #include <base/stringprintf.h> #include <selinux/android.h> #include <base/logging.h> #include <inttypes.h> #include <sys/capability.h> #include <sys/file.h> #include <unistd.h> using android::base::StringPrintf; using android::base::StringPrintf; Loading @@ -38,6 +41,8 @@ dir_rec_t android_media_dir; dir_rec_t android_mnt_expand_dir; dir_rec_t android_mnt_expand_dir; dir_rec_array_t android_system_dirs; dir_rec_array_t android_system_dirs; static const char* kCpPath = "/system/bin/cp"; int install(const char *uuid, const char *pkgname, uid_t uid, gid_t gid, const char *seinfo) int install(const char *uuid, const char *pkgname, uid_t uid, gid_t gid, const char *seinfo) { { if ((uid < AID_SYSTEM) || (gid < AID_SYSTEM)) { if ((uid < AID_SYSTEM) || (gid < AID_SYSTEM)) { Loading Loading @@ -172,6 +177,80 @@ int make_user_data(const char *uuid, const char *pkgname, uid_t uid, userid_t us return 0; return 0; } } int move_user_data(const char *from_uuid, const char *to_uuid, const char *package_name, appid_t appid, const char* seinfo) { std::vector<userid_t> users = get_known_users(from_uuid); // Copy package private data for all known users for (auto user : users) { std::string from(create_package_data_path(from_uuid, package_name, user)); std::string to(create_package_data_path(to_uuid, package_name, user)); std::string to_user(create_data_user_path(to_uuid, user)); // Data source may not exist for all users; that's okay if (access(from.c_str(), F_OK) != 0) { LOG(INFO) << "Missing source " << from; continue; } std::string user_path(create_data_user_path(to_uuid, user)); if (fs_prepare_dir(user_path.c_str(), 0771, AID_SYSTEM, AID_SYSTEM) != 0) { LOG(ERROR) << "Failed to prepare user target " << user_path; goto fail; } uid_t uid = multiuser_get_uid(user, appid); if (make_user_data(to_uuid, package_name, uid, user, seinfo) != 0) { LOG(ERROR) << "Failed to create package target " << to; goto fail; } char *argv[] = { (char*) kCpPath, (char*) "-F", /* delete any existing destination file first (--remove-destination) */ (char*) "-p", /* preserve timestamps, ownership, and permissions */ (char*) "-R", /* recurse into subdirectories (DEST must be a directory) */ (char*) "-P", /* Do not follow symlinks [default] */ (char*) "-d", /* don't dereference symlinks */ (char*) from.c_str(), (char*) to_user.c_str() }; LOG(DEBUG) << "Copying " << from << " to " << to; int rc = android_fork_execvp(ARRAY_SIZE(argv), argv, NULL, false, true); if (rc != 0) { LOG(ERROR) << "Failed copying " << from << " to " << to << ": status " << rc; goto fail; } if (restorecon_data(to_uuid, package_name, seinfo, uid) != 0) { LOG(ERROR) << "Failed to restorecon " << to; goto fail; } } // Copy successful, so delete old data for (auto user : users) { std::string from(create_package_data_path(from_uuid, package_name, user)); if (delete_dir_contents(from.c_str(), 1, NULL) != 0) { LOG(WARNING) << "Failed to delete " << from; } } return 0; fail: // Nuke everything we might have already copied for (auto user : users) { std::string to(create_package_data_path(to_uuid, package_name, user)); if (delete_dir_contents(to.c_str(), 1, NULL) != 0) { LOG(WARNING) << "Failed to rollback " << to; } } return -1; } int make_user_config(userid_t userid) int make_user_config(userid_t userid) { { if (ensure_config_user_dirs(userid) == -1) { if (ensure_config_user_dirs(userid) == -1) { Loading Loading @@ -1592,7 +1671,7 @@ int restorecon_data(const char* uuid, const char* pkgName, continue; continue; } } std::string pkgdir(StringPrintf("%s/%s/%s", userdir.c_str(), user, pkgName)); std::string pkgdir(StringPrintf("%s%s/%s", userdir.c_str(), user, pkgName)); if (stat(pkgdir.c_str(), &s) < 0) { if (stat(pkgdir.c_str(), &s) < 0) { continue; continue; } } Loading
cmds/installd/installd.cpp +15 −46 Original line number Original line Diff line number Diff line Loading @@ -14,14 +14,15 @@ ** limitations under the License. ** limitations under the License. */ */ #include "installd.h" #include <base/logging.h> #include <sys/capability.h> #include <sys/capability.h> #include <sys/prctl.h> #include <sys/prctl.h> #include <selinux/android.h> #include <selinux/android.h> #include <selinux/avc.h> #include <selinux/avc.h> #include "installd.h" #define BUFFER_MAX 1024 /* input buffer for commands */ #define BUFFER_MAX 1024 /* input buffer for commands */ #define TOKEN_MAX 16 /* max number of arguments in buffer */ #define TOKEN_MAX 16 /* max number of arguments in buffer */ #define REPLY_MAX 256 /* largest reply allowed */ #define REPLY_MAX 256 /* largest reply allowed */ Loading Loading @@ -123,6 +124,12 @@ static int do_rm_user_data(char **arg, char reply[REPLY_MAX] __unused) return delete_user_data(parse_null(arg[0]), arg[1], atoi(arg[2])); /* uuid, pkgname, userid */ return delete_user_data(parse_null(arg[0]), arg[1], atoi(arg[2])); /* uuid, pkgname, userid */ } } static int do_mv_user_data(char **arg, char reply[REPLY_MAX] __unused) { // from_uuid, to_uuid, pkgname, appid, seinfo return move_user_data(parse_null(arg[0]), parse_null(arg[1]), arg[2], atoi(arg[3]), arg[4]); } static int do_mk_user_data(char **arg, char reply[REPLY_MAX] __unused) static int do_mk_user_data(char **arg, char reply[REPLY_MAX] __unused) { { return make_user_data(parse_null(arg[0]), arg[1], atoi(arg[2]), atoi(arg[3]), arg[4]); return make_user_data(parse_null(arg[0]), arg[1], atoi(arg[2]), atoi(arg[3]), arg[4]); Loading Loading @@ -193,6 +200,7 @@ struct cmdinfo cmds[] = { { "rmcodecache", 3, do_rm_code_cache }, { "rmcodecache", 3, do_rm_code_cache }, { "getsize", 8, do_get_size }, { "getsize", 8, do_get_size }, { "rmuserdata", 3, do_rm_user_data }, { "rmuserdata", 3, do_rm_user_data }, { "mvuserdata", 5, do_mv_user_data }, { "movefiles", 0, do_movefiles }, { "movefiles", 0, do_movefiles }, { "linklib", 4, do_linklib }, { "linklib", 4, do_linklib }, { "mkuserdata", 5, do_mk_user_data }, { "mkuserdata", 5, do_mk_user_data }, Loading Loading @@ -621,46 +629,6 @@ fail: return res; 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[CAP_TO_INDEX(CAP_FOWNER)].permitted |= CAP_TO_MASK(CAP_FOWNER); 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); } } static int log_callback(int type, const char *fmt, ...) { static int log_callback(int type, const char *fmt, ...) { va_list ap; va_list ap; int priority; int priority; Loading @@ -682,13 +650,16 @@ static int log_callback(int type, const char *fmt, ...) { return 0; return 0; } } int main(const int argc __unused, const char *argv[] __unused) { int main(const int argc __unused, char *argv[]) { char buf[BUFFER_MAX]; char buf[BUFFER_MAX]; struct sockaddr addr; struct sockaddr addr; socklen_t alen; socklen_t alen; int lsocket, s; int lsocket, s; int selinux_enabled = (is_selinux_enabled() > 0); int selinux_enabled = (is_selinux_enabled() > 0); setenv("ANDROID_LOG_TAGS", "*:v", 1); android::base::InitLogging(argv); ALOGI("installd firing up\n"); ALOGI("installd firing up\n"); union selinux_callback cb; union selinux_callback cb; Loading @@ -710,8 +681,6 @@ int main(const int argc __unused, const char *argv[] __unused) { exit(1); exit(1); } } drop_privileges(); lsocket = android_get_control_socket(SOCKET_PATH); lsocket = android_get_control_socket(SOCKET_PATH); if (lsocket < 0) { if (lsocket < 0) { ALOGE("Failed to get socket from environment: %s\n", strerror(errno)); ALOGE("Failed to get socket from environment: %s\n", strerror(errno)); Loading
cmds/installd/installd.h +11 −1 Original line number Original line Diff line number Diff line Loading @@ -32,6 +32,7 @@ #include <sys/types.h> #include <sys/types.h> #include <sys/wait.h> #include <sys/wait.h> #include <string> #include <string> #include <vector> #include <cutils/fs.h> #include <cutils/fs.h> #include <cutils/sockets.h> #include <cutils/sockets.h> Loading Loading @@ -89,6 +90,8 @@ #define DEXOPT_PATCHOAT_NEEDED 2 #define DEXOPT_PATCHOAT_NEEDED 2 #define DEXOPT_SELF_PATCHOAT_NEEDED 3 #define DEXOPT_SELF_PATCHOAT_NEEDED 3 #define ARRAY_SIZE(a) (sizeof(a) / sizeof(*(a))) /* data structures */ /* data structures */ typedef struct { typedef struct { Loading Loading @@ -154,6 +157,8 @@ std::string create_data_user_path(const char* volume_uuid, userid_t userid); std::string create_data_media_path(const char* volume_uuid, userid_t userid); std::string create_data_media_path(const char* volume_uuid, userid_t userid); std::vector<userid_t> get_known_users(const char* volume_uuid); int create_user_config_path(char path[PKG_PATH_MAX], userid_t userid); int create_user_config_path(char path[PKG_PATH_MAX], userid_t userid); int create_move_path(char path[PKG_PATH_MAX], int create_move_path(char path[PKG_PATH_MAX], Loading Loading @@ -214,7 +219,10 @@ int uninstall(const char *uuid, const char *pkgname, userid_t userid); int renamepkg(const char *oldpkgname, const char *newpkgname); int renamepkg(const char *oldpkgname, const char *newpkgname); int fix_uid(const char *uuid, const char *pkgname, uid_t uid, gid_t gid); int fix_uid(const char *uuid, const char *pkgname, uid_t uid, gid_t gid); int delete_user_data(const char *uuid, const char *pkgname, userid_t userid); int delete_user_data(const char *uuid, const char *pkgname, userid_t userid); int make_user_data(const char *uuid, const char *pkgname, uid_t uid, userid_t userid, const char* seinfo); int make_user_data(const char *uuid, const char *pkgname, uid_t uid, userid_t userid, const char* seinfo); int move_user_data(const char* from_uuid, const char *to_uuid, const char *package_name, appid_t appid, const char* seinfo); int make_user_config(userid_t userid); int make_user_config(userid_t userid); int delete_user(const char *uuid, userid_t userid); int delete_user(const char *uuid, userid_t userid); int delete_cache(const char *uuid, const char *pkgname, userid_t userid); int delete_cache(const char *uuid, const char *pkgname, userid_t userid); Loading @@ -238,3 +246,5 @@ int create_oat_dir(const char* oat_dir, const char *instruction_set); int rm_package_dir(const char* apk_path); int rm_package_dir(const char* apk_path); int calculate_oat_file_path(char path[PKG_PATH_MAX], const char *oat_dir, const char *apk_path, int calculate_oat_file_path(char path[PKG_PATH_MAX], const char *oat_dir, const char *apk_path, const char *instruction_set); const char *instruction_set); int move_package_dir(char path[PKG_PATH_MAX], const char *oat_dir, const char *apk_path, const char *instruction_set);
cmds/installd/utils.cpp +32 −0 Original line number Original line Diff line number Diff line Loading @@ -99,6 +99,38 @@ std::string create_data_media_path(const char* volume_uuid, userid_t userid) { return StringPrintf("%s/media/%u", create_data_path(volume_uuid).c_str(), userid); return StringPrintf("%s/media/%u", create_data_path(volume_uuid).c_str(), userid); } } std::vector<userid_t> get_known_users(const char* volume_uuid) { std::vector<userid_t> users; // We always have an owner users.push_back(0); std::string path(create_data_path(volume_uuid) + "/" + SECONDARY_USER_PREFIX); DIR* dir = opendir(path.c_str()); if (dir == NULL) { // Unable to discover other users, but at least return owner PLOG(ERROR) << "Failed to opendir " << path; return users; } struct dirent* ent; while ((ent = readdir(dir))) { if (ent->d_type != DT_DIR) { continue; } char* end; userid_t user = strtol(ent->d_name, &end, 10); if (*end == '\0' && user != 0) { LOG(DEBUG) << "Found valid user " << user; users.push_back(user); } } closedir(dir); return users; } /** /** * Create the path name for config for a certain userid. * Create the path name for config for a certain userid. * Returns 0 on success, and -1 on failure. * Returns 0 on success, and -1 on failure. Loading