Loading cmds/installd/Android.mk +24 −3 Original line number Diff line number Diff line ifneq ($(TARGET_SIMULATOR),true) LOCAL_PATH := $(call my-dir) common_src_files := \ commands.c utils.c # # Static library used in testing and executable # include $(CLEAR_VARS) LOCAL_SRC_FILES := \ installd.c commands.c utils.c $(common_src_files) LOCAL_MODULE := libinstalld LOCAL_MODULE_TAGS := eng tests #LOCAL_C_INCLUDES := \ # $(call include-path-for, system-core)/cutils include $(BUILD_STATIC_LIBRARY) # # Executable # include $(CLEAR_VARS) LOCAL_SRC_FILES := \ installd.c \ $(common_src_files) LOCAL_SHARED_LIBRARIES := \ libcutils Loading cmds/installd/commands.c +42 −62 Original line number Diff line number Diff line Loading @@ -17,6 +17,13 @@ #include "installd.h" #include <diskusage/dirsize.h> /* Directory records that are used in execution of commands. */ dir_rec_t android_data_dir; dir_rec_t android_asec_dir; dir_rec_t android_app_dir; dir_rec_t android_app_private_dir; dir_rec_array_t android_system_dirs; int install(const char *pkgname, uid_t uid, gid_t gid) { char pkgdir[PKG_PATH_MAX]; Loading @@ -27,10 +34,15 @@ int install(const char *pkgname, uid_t uid, gid_t gid) return -1; } if (create_pkg_path(pkgdir, PKG_DIR_PREFIX, pkgname, PKG_DIR_POSTFIX)) if (create_pkg_path(pkgdir, pkgname, PKG_DIR_POSTFIX, 0)) { LOGE("cannot create package path\n"); return -1; if (create_pkg_path(libdir, PKG_LIB_PREFIX, pkgname, PKG_LIB_POSTFIX)) } if (create_pkg_path(libdir, pkgname, PKG_LIB_POSTFIX, 0)) { LOGE("cannot create package lib path\n"); return -1; } if (mkdir(pkgdir, 0751) < 0) { LOGE("cannot create dir '%s': %s\n", pkgdir, strerror(errno)); Loading Loading @@ -59,7 +71,7 @@ int uninstall(const char *pkgname) { char pkgdir[PKG_PATH_MAX]; if (create_pkg_path(pkgdir, PKG_DIR_PREFIX, pkgname, PKG_DIR_POSTFIX)) if (create_pkg_path(pkgdir, pkgname, PKG_DIR_POSTFIX, 0)) return -1; /* delete contents AND directory, no exceptions */ Loading @@ -71,9 +83,9 @@ int renamepkg(const char *oldpkgname, const char *newpkgname) char oldpkgdir[PKG_PATH_MAX]; char newpkgdir[PKG_PATH_MAX]; if (create_pkg_path(oldpkgdir, PKG_DIR_PREFIX, oldpkgname, PKG_DIR_POSTFIX)) if (create_pkg_path(oldpkgdir, oldpkgname, PKG_DIR_POSTFIX, 0)) return -1; if (create_pkg_path(newpkgdir, PKG_DIR_PREFIX, newpkgname, PKG_DIR_POSTFIX)) if (create_pkg_path(newpkgdir, newpkgname, PKG_DIR_POSTFIX, 0)) return -1; if (rename(oldpkgdir, newpkgdir) < 0) { Loading @@ -87,7 +99,7 @@ int delete_user_data(const char *pkgname) { char pkgdir[PKG_PATH_MAX]; if (create_pkg_path(pkgdir, PKG_DIR_PREFIX, pkgname, PKG_DIR_POSTFIX)) if (create_pkg_path(pkgdir, pkgname, PKG_DIR_POSTFIX, 0)) return -1; /* delete contents, excluding "lib", but not the directory itself */ Loading @@ -98,7 +110,7 @@ int delete_cache(const char *pkgname) { char cachedir[PKG_PATH_MAX]; if (create_pkg_path(cachedir, CACHE_DIR_PREFIX, pkgname, CACHE_DIR_POSTFIX)) if (create_pkg_path(cachedir, pkgname, CACHE_DIR_POSTFIX, 0)) return -1; /* delete contents, not the directory, no exceptions */ Loading @@ -108,10 +120,10 @@ int delete_cache(const char *pkgname) static int64_t disk_free() { struct statfs sfs; if (statfs(PKG_DIR_PREFIX, &sfs) == 0) { if (statfs(android_data_dir.path, &sfs) == 0) { return sfs.f_bavail * sfs.f_bsize; } else { LOGE("Couldn't statfs " PKG_DIR_PREFIX ": %s\n", strerror(errno)); LOGE("Couldn't statfs %s: %s\n", android_data_dir.path, strerror(errno)); return -1; } } Loading @@ -137,9 +149,9 @@ int free_cache(int64_t free_size) LOGI("free_cache(%" PRId64 ") avail %" PRId64 "\n", free_size, avail); if (avail >= free_size) return 0; d = opendir(PKG_DIR_PREFIX); d = opendir(android_data_dir.path); if (d == NULL) { LOGE("cannot open %s: %s\n", PKG_DIR_PREFIX, strerror(errno)); LOGE("cannot open %s: %s\n", android_data_dir.path, strerror(errno)); return -1; } dfd = dirfd(d); Loading Loading @@ -172,43 +184,13 @@ int free_cache(int64_t free_size) return -1; } /* used by move_dex, rm_dex, etc to ensure that the provided paths * don't point anywhere other than at the APK_DIR_PREFIX */ static int is_valid_apk_path(const char *path) { int len = strlen(APK_DIR_PREFIX); int nosubdircheck = 0; if (strncmp(path, APK_DIR_PREFIX, len)) { len = strlen(PROTECTED_DIR_PREFIX); if (strncmp(path, PROTECTED_DIR_PREFIX, len)) { len = strlen(SDCARD_DIR_PREFIX); if (strncmp(path, SDCARD_DIR_PREFIX, len)) { LOGE("invalid apk path '%s' (bad prefix)\n", path); return 0; } else { nosubdircheck = 1; } } } if ((nosubdircheck != 1) && strchr(path + len, '/')) { LOGE("invalid apk path '%s' (subdir?)\n", path); return 0; } if (path[len] == '.') { LOGE("invalid apk path '%s' (trickery)\n", path); return 0; } return 1; } int move_dex(const char *src, const char *dst) { char src_dex[PKG_PATH_MAX]; char dst_dex[PKG_PATH_MAX]; if (!is_valid_apk_path(src)) return -1; if (!is_valid_apk_path(dst)) return -1; if (validate_apk_path(src)) return -1; if (validate_apk_path(dst)) return -1; if (create_cache_path(src_dex, src)) return -1; if (create_cache_path(dst_dex, dst)) return -1; Loading @@ -226,7 +208,7 @@ int rm_dex(const char *path) { char dex_path[PKG_PATH_MAX]; if (!is_valid_apk_path(path)) return -1; if (validate_apk_path(path)) return -1; if (create_cache_path(dex_path, path)) return -1; LOGI("unlink %s\n", dex_path); Loading @@ -245,7 +227,7 @@ int protect(char *pkgname, gid_t gid) if (gid < AID_SYSTEM) return -1; if (create_pkg_path(pkgpath, PROTECTED_DIR_PREFIX, pkgname, ".apk")) if (create_pkg_path_in_dir(pkgpath, &android_app_private_dir, pkgname, ".apk")) return -1; if (stat(pkgpath, &s) < 0) return -1; Loading Loading @@ -280,8 +262,8 @@ int get_size(const char *pkgname, const char *apkpath, /* count the source apk as code -- but only if it's not * on the /system partition and its not on the sdcard. */ if (strncmp(apkpath, "/system", 7) != 0 && strncmp(apkpath, SDCARD_DIR_PREFIX, 7) != 0) { if (validate_system_app_path(apkpath) && strncmp(apkpath, android_asec_dir.path, android_asec_dir.len) != 0) { if (stat(apkpath, &s) == 0) { codesize += stat_size(&s); } Loading @@ -300,7 +282,7 @@ int get_size(const char *pkgname, const char *apkpath, } } if (create_pkg_path(path, PKG_DIR_PREFIX, pkgname, PKG_DIR_POSTFIX)) { if (create_pkg_path(path, pkgname, PKG_DIR_POSTFIX, 0)) { goto done; } Loading Loading @@ -544,15 +526,15 @@ fail: } int create_move_path(char path[PKG_PATH_MAX], const char* prefix, const char* pkgname, const char* leaf) const char* leaf, uid_t persona) { if ((strlen(prefix) + strlen(pkgname) + strlen(leaf) + 1) >= PKG_PATH_MAX) { if ((android_data_dir.len + strlen(pkgname) + strlen(leaf) + 1) >= PKG_PATH_MAX) { return -1; } sprintf(path, "%s%s/%s", prefix, pkgname, leaf); sprintf(path, "%s%s%s/%s", android_data_dir.path, PRIMARY_USER_PREFIX, pkgname, leaf); return 0; } Loading Loading @@ -720,8 +702,8 @@ int movefiles() // Skip -- source package no longer exists. } else { LOGV("Move file: %s (from %s to %s)\n", buf+bufp, srcpkg, dstpkg); if (!create_move_path(srcpath, PKG_DIR_PREFIX, srcpkg, buf+bufp) && !create_move_path(dstpath, PKG_DIR_PREFIX, dstpkg, buf+bufp)) { if (!create_move_path(srcpath, srcpkg, buf+bufp, 0) && !create_move_path(dstpath, dstpkg, buf+bufp, 0)) { movefileordir(srcpath, dstpath, strlen(dstpath)-strlen(buf+bufp), dstuid, dstgid, &s); Loading Loading @@ -750,8 +732,7 @@ int movefiles() UPDATE_COMMANDS_DIR_PREFIX, name, div); } if (srcpkg[0] != 0) { if (!create_pkg_path(srcpath, PKG_DIR_PREFIX, srcpkg, PKG_DIR_POSTFIX)) { if (!create_pkg_path(srcpath, srcpkg, PKG_DIR_POSTFIX, 0)) { if (lstat(srcpath, &s) < 0) { // Package no longer exists -- skip. srcpkg[0] = 0; Loading @@ -762,8 +743,7 @@ int movefiles() div, UPDATE_COMMANDS_DIR_PREFIX, name); } if (srcpkg[0] != 0) { if (!create_pkg_path(dstpath, PKG_DIR_PREFIX, dstpkg, PKG_DIR_POSTFIX)) { if (!create_pkg_path(dstpath, dstpkg, PKG_DIR_POSTFIX, 0)) { if (lstat(dstpath, &s) == 0) { dstuid = s.st_uid; dstgid = s.st_gid; Loading cmds/installd/installd.c +66 −2 Original line number Diff line number Diff line Loading @@ -21,7 +21,6 @@ #define TOKEN_MAX 8 /* max number of arguments in buffer */ #define REPLY_MAX 256 /* largest reply allowed */ static int do_ping(char **arg, char reply[REPLY_MAX]) { return 0; Loading Loading @@ -235,12 +234,77 @@ done: return 0; } /** * Initialize all the global variables that are used elsewhere. Returns 0 upon * success and -1 on error. */ void free_globals() { size_t i; for (i = 0; i < android_system_dirs.count; i++) { if (android_system_dirs.dirs[i].path != NULL) { free(android_system_dirs.dirs[i].path); } } free(android_system_dirs.dirs); } int initialize_globals() { // Get the android data directory. if (get_path_from_env(&android_data_dir, "ANDROID_DATA") < 0) { return -1; } // Get the android app directory. if (copy_and_append(&android_app_dir, &android_data_dir, APP_SUBDIR) < 0) { return -1; } // Get the android protected app directory. if (copy_and_append(&android_app_private_dir, &android_data_dir, PRIVATE_APP_SUBDIR) < 0) { return -1; } // Get the sd-card ASEC mount point. if (get_path_from_env(&android_asec_dir, "ASEC_MOUNTPOINT") < 0) { return -1; } // Take note of the system and vendor directories. android_system_dirs.count = 2; android_system_dirs.dirs = calloc(android_system_dirs.count, sizeof(dir_rec_t)); if (android_system_dirs.dirs == NULL) { LOGE("Couldn't allocate array for dirs; aborting\n"); return -1; } // system if (get_path_from_env(&android_system_dirs.dirs[0], "ANDROID_ROOT") < 0) { free_globals(); return -1; } // vendor // TODO replace this with an environment variable (doesn't exist yet) android_system_dirs.dirs[1].path = "/vendor/"; android_system_dirs.dirs[1].len = strlen(android_system_dirs.dirs[1].path); return 0; } int main(const int argc, const char *argv[]) { char buf[BUFFER_MAX]; struct sockaddr addr; socklen_t alen; int lsocket, s, count; if (initialize_globals() < 0) { LOGE("Could not initialize globals; exiting.\n"); exit(1); } lsocket = android_get_control_socket(SOCKET_PATH); if (lsocket < 0) { LOGE("Failed to get socket from environment: %s\n", strerror(errno)); Loading cmds/installd/installd.h +45 −10 Original line number Diff line number Diff line Loading @@ -49,21 +49,20 @@ /* elements combined with a valid package name to form paths */ #define PKG_DIR_PREFIX "/data/data/" #define PRIMARY_USER_PREFIX "data/" #define SECONDARY_USER_PREFIX "user/" #define PKG_DIR_POSTFIX "" #define PKG_LIB_PREFIX "/data/data/" #define PKG_LIB_POSTFIX "/lib" #define CACHE_DIR_PREFIX "/data/data/" #define CACHE_DIR_POSTFIX "/cache" #define APK_DIR_PREFIX "/data/app/" #define APP_SUBDIR "app/" // sub-directory under ANDROID_DATA /* other handy constants */ #define PROTECTED_DIR_PREFIX "/data/app-private/" #define SDCARD_DIR_PREFIX getenv("ASEC_MOUNTPOINT") #define PRIVATE_APP_SUBDIR "app-private/" // sub-directory under ANDROID_DATA #define DALVIK_CACHE_PREFIX "/data/dalvik-cache/" #define DALVIK_CACHE_POSTFIX "/classes.dex" Loading @@ -73,14 +72,38 @@ #define PKG_NAME_MAX 128 /* largest allowed package name */ #define PKG_PATH_MAX 256 /* max size of any path we use */ /* data structures */ typedef struct { char* path; size_t len; } dir_rec_t; typedef struct { size_t count; dir_rec_t* dirs; } dir_rec_array_t; extern dir_rec_t android_app_dir; extern dir_rec_t android_app_private_dir; extern dir_rec_t android_data_dir; extern dir_rec_t android_asec_dir; extern dir_rec_array_t android_system_dirs; /* util.c */ int create_pkg_path(char path[PKG_PATH_MAX], const char *prefix, int create_pkg_path_in_dir(char path[PKG_PATH_MAX], const dir_rec_t* dir, const char* pkgname, const char* postfix); int create_pkg_path(char path[PKG_PATH_MAX], const char *pkgname, const char *postfix, uid_t persona); int is_valid_package_name(const char* pkgname); int create_cache_path(char path[PKG_PATH_MAX], const char *src); int delete_dir_contents(const char *pathname, Loading @@ -89,6 +112,18 @@ int delete_dir_contents(const char *pathname, int delete_dir_contents_fd(int dfd, const char *name); int validate_system_app_path(const char* path); int get_path_from_env(dir_rec_t* rec, const char* var); int get_path_from_string(dir_rec_t* rec, const char* path); int copy_and_append(dir_rec_t* dst, const dir_rec_t* src, const char* suffix); int validate_apk_path(const char *path); int append_and_increment(char** dst, const char* src, size_t* dst_size); /* commands.c */ int install(const char *pkgname, uid_t uid, gid_t gid); Loading cmds/installd/tests/Android.mk 0 → 100644 +42 −0 Original line number Diff line number Diff line # Build the unit tests for installd LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) ifneq ($(TARGET_SIMULATOR),true) # Build the unit tests. test_src_files := \ installd_utils_test.cpp shared_libraries := \ libutils \ libcutils \ libstlport static_libraries := \ libinstalld \ libdiskusage \ libgtest \ libgtest_main c_includes := \ frameworks/base/cmds/installd \ bionic \ bionic/libstdc++/include \ external/gtest/include \ external/stlport/stlport module_tags := eng tests $(foreach file,$(test_src_files), \ $(eval include $(CLEAR_VARS)) \ $(eval LOCAL_SHARED_LIBRARIES := $(shared_libraries)) \ $(eval LOCAL_STATIC_LIBRARIES := $(static_libraries)) \ $(eval LOCAL_SRC_FILES := $(file)) \ $(eval LOCAL_C_INCLUDES := $(c_includes)) \ $(eval LOCAL_MODULE := $(notdir $(file:%.cpp=%))) \ $(eval LOCAL_MODULE_TAGS := $(module_tags)) \ $(eval include $(BUILD_EXECUTABLE)) \ ) endif Loading
cmds/installd/Android.mk +24 −3 Original line number Diff line number Diff line ifneq ($(TARGET_SIMULATOR),true) LOCAL_PATH := $(call my-dir) common_src_files := \ commands.c utils.c # # Static library used in testing and executable # include $(CLEAR_VARS) LOCAL_SRC_FILES := \ installd.c commands.c utils.c $(common_src_files) LOCAL_MODULE := libinstalld LOCAL_MODULE_TAGS := eng tests #LOCAL_C_INCLUDES := \ # $(call include-path-for, system-core)/cutils include $(BUILD_STATIC_LIBRARY) # # Executable # include $(CLEAR_VARS) LOCAL_SRC_FILES := \ installd.c \ $(common_src_files) LOCAL_SHARED_LIBRARIES := \ libcutils Loading
cmds/installd/commands.c +42 −62 Original line number Diff line number Diff line Loading @@ -17,6 +17,13 @@ #include "installd.h" #include <diskusage/dirsize.h> /* Directory records that are used in execution of commands. */ dir_rec_t android_data_dir; dir_rec_t android_asec_dir; dir_rec_t android_app_dir; dir_rec_t android_app_private_dir; dir_rec_array_t android_system_dirs; int install(const char *pkgname, uid_t uid, gid_t gid) { char pkgdir[PKG_PATH_MAX]; Loading @@ -27,10 +34,15 @@ int install(const char *pkgname, uid_t uid, gid_t gid) return -1; } if (create_pkg_path(pkgdir, PKG_DIR_PREFIX, pkgname, PKG_DIR_POSTFIX)) if (create_pkg_path(pkgdir, pkgname, PKG_DIR_POSTFIX, 0)) { LOGE("cannot create package path\n"); return -1; if (create_pkg_path(libdir, PKG_LIB_PREFIX, pkgname, PKG_LIB_POSTFIX)) } if (create_pkg_path(libdir, pkgname, PKG_LIB_POSTFIX, 0)) { LOGE("cannot create package lib path\n"); return -1; } if (mkdir(pkgdir, 0751) < 0) { LOGE("cannot create dir '%s': %s\n", pkgdir, strerror(errno)); Loading Loading @@ -59,7 +71,7 @@ int uninstall(const char *pkgname) { char pkgdir[PKG_PATH_MAX]; if (create_pkg_path(pkgdir, PKG_DIR_PREFIX, pkgname, PKG_DIR_POSTFIX)) if (create_pkg_path(pkgdir, pkgname, PKG_DIR_POSTFIX, 0)) return -1; /* delete contents AND directory, no exceptions */ Loading @@ -71,9 +83,9 @@ int renamepkg(const char *oldpkgname, const char *newpkgname) char oldpkgdir[PKG_PATH_MAX]; char newpkgdir[PKG_PATH_MAX]; if (create_pkg_path(oldpkgdir, PKG_DIR_PREFIX, oldpkgname, PKG_DIR_POSTFIX)) if (create_pkg_path(oldpkgdir, oldpkgname, PKG_DIR_POSTFIX, 0)) return -1; if (create_pkg_path(newpkgdir, PKG_DIR_PREFIX, newpkgname, PKG_DIR_POSTFIX)) if (create_pkg_path(newpkgdir, newpkgname, PKG_DIR_POSTFIX, 0)) return -1; if (rename(oldpkgdir, newpkgdir) < 0) { Loading @@ -87,7 +99,7 @@ int delete_user_data(const char *pkgname) { char pkgdir[PKG_PATH_MAX]; if (create_pkg_path(pkgdir, PKG_DIR_PREFIX, pkgname, PKG_DIR_POSTFIX)) if (create_pkg_path(pkgdir, pkgname, PKG_DIR_POSTFIX, 0)) return -1; /* delete contents, excluding "lib", but not the directory itself */ Loading @@ -98,7 +110,7 @@ int delete_cache(const char *pkgname) { char cachedir[PKG_PATH_MAX]; if (create_pkg_path(cachedir, CACHE_DIR_PREFIX, pkgname, CACHE_DIR_POSTFIX)) if (create_pkg_path(cachedir, pkgname, CACHE_DIR_POSTFIX, 0)) return -1; /* delete contents, not the directory, no exceptions */ Loading @@ -108,10 +120,10 @@ int delete_cache(const char *pkgname) static int64_t disk_free() { struct statfs sfs; if (statfs(PKG_DIR_PREFIX, &sfs) == 0) { if (statfs(android_data_dir.path, &sfs) == 0) { return sfs.f_bavail * sfs.f_bsize; } else { LOGE("Couldn't statfs " PKG_DIR_PREFIX ": %s\n", strerror(errno)); LOGE("Couldn't statfs %s: %s\n", android_data_dir.path, strerror(errno)); return -1; } } Loading @@ -137,9 +149,9 @@ int free_cache(int64_t free_size) LOGI("free_cache(%" PRId64 ") avail %" PRId64 "\n", free_size, avail); if (avail >= free_size) return 0; d = opendir(PKG_DIR_PREFIX); d = opendir(android_data_dir.path); if (d == NULL) { LOGE("cannot open %s: %s\n", PKG_DIR_PREFIX, strerror(errno)); LOGE("cannot open %s: %s\n", android_data_dir.path, strerror(errno)); return -1; } dfd = dirfd(d); Loading Loading @@ -172,43 +184,13 @@ int free_cache(int64_t free_size) return -1; } /* used by move_dex, rm_dex, etc to ensure that the provided paths * don't point anywhere other than at the APK_DIR_PREFIX */ static int is_valid_apk_path(const char *path) { int len = strlen(APK_DIR_PREFIX); int nosubdircheck = 0; if (strncmp(path, APK_DIR_PREFIX, len)) { len = strlen(PROTECTED_DIR_PREFIX); if (strncmp(path, PROTECTED_DIR_PREFIX, len)) { len = strlen(SDCARD_DIR_PREFIX); if (strncmp(path, SDCARD_DIR_PREFIX, len)) { LOGE("invalid apk path '%s' (bad prefix)\n", path); return 0; } else { nosubdircheck = 1; } } } if ((nosubdircheck != 1) && strchr(path + len, '/')) { LOGE("invalid apk path '%s' (subdir?)\n", path); return 0; } if (path[len] == '.') { LOGE("invalid apk path '%s' (trickery)\n", path); return 0; } return 1; } int move_dex(const char *src, const char *dst) { char src_dex[PKG_PATH_MAX]; char dst_dex[PKG_PATH_MAX]; if (!is_valid_apk_path(src)) return -1; if (!is_valid_apk_path(dst)) return -1; if (validate_apk_path(src)) return -1; if (validate_apk_path(dst)) return -1; if (create_cache_path(src_dex, src)) return -1; if (create_cache_path(dst_dex, dst)) return -1; Loading @@ -226,7 +208,7 @@ int rm_dex(const char *path) { char dex_path[PKG_PATH_MAX]; if (!is_valid_apk_path(path)) return -1; if (validate_apk_path(path)) return -1; if (create_cache_path(dex_path, path)) return -1; LOGI("unlink %s\n", dex_path); Loading @@ -245,7 +227,7 @@ int protect(char *pkgname, gid_t gid) if (gid < AID_SYSTEM) return -1; if (create_pkg_path(pkgpath, PROTECTED_DIR_PREFIX, pkgname, ".apk")) if (create_pkg_path_in_dir(pkgpath, &android_app_private_dir, pkgname, ".apk")) return -1; if (stat(pkgpath, &s) < 0) return -1; Loading Loading @@ -280,8 +262,8 @@ int get_size(const char *pkgname, const char *apkpath, /* count the source apk as code -- but only if it's not * on the /system partition and its not on the sdcard. */ if (strncmp(apkpath, "/system", 7) != 0 && strncmp(apkpath, SDCARD_DIR_PREFIX, 7) != 0) { if (validate_system_app_path(apkpath) && strncmp(apkpath, android_asec_dir.path, android_asec_dir.len) != 0) { if (stat(apkpath, &s) == 0) { codesize += stat_size(&s); } Loading @@ -300,7 +282,7 @@ int get_size(const char *pkgname, const char *apkpath, } } if (create_pkg_path(path, PKG_DIR_PREFIX, pkgname, PKG_DIR_POSTFIX)) { if (create_pkg_path(path, pkgname, PKG_DIR_POSTFIX, 0)) { goto done; } Loading Loading @@ -544,15 +526,15 @@ fail: } int create_move_path(char path[PKG_PATH_MAX], const char* prefix, const char* pkgname, const char* leaf) const char* leaf, uid_t persona) { if ((strlen(prefix) + strlen(pkgname) + strlen(leaf) + 1) >= PKG_PATH_MAX) { if ((android_data_dir.len + strlen(pkgname) + strlen(leaf) + 1) >= PKG_PATH_MAX) { return -1; } sprintf(path, "%s%s/%s", prefix, pkgname, leaf); sprintf(path, "%s%s%s/%s", android_data_dir.path, PRIMARY_USER_PREFIX, pkgname, leaf); return 0; } Loading Loading @@ -720,8 +702,8 @@ int movefiles() // Skip -- source package no longer exists. } else { LOGV("Move file: %s (from %s to %s)\n", buf+bufp, srcpkg, dstpkg); if (!create_move_path(srcpath, PKG_DIR_PREFIX, srcpkg, buf+bufp) && !create_move_path(dstpath, PKG_DIR_PREFIX, dstpkg, buf+bufp)) { if (!create_move_path(srcpath, srcpkg, buf+bufp, 0) && !create_move_path(dstpath, dstpkg, buf+bufp, 0)) { movefileordir(srcpath, dstpath, strlen(dstpath)-strlen(buf+bufp), dstuid, dstgid, &s); Loading Loading @@ -750,8 +732,7 @@ int movefiles() UPDATE_COMMANDS_DIR_PREFIX, name, div); } if (srcpkg[0] != 0) { if (!create_pkg_path(srcpath, PKG_DIR_PREFIX, srcpkg, PKG_DIR_POSTFIX)) { if (!create_pkg_path(srcpath, srcpkg, PKG_DIR_POSTFIX, 0)) { if (lstat(srcpath, &s) < 0) { // Package no longer exists -- skip. srcpkg[0] = 0; Loading @@ -762,8 +743,7 @@ int movefiles() div, UPDATE_COMMANDS_DIR_PREFIX, name); } if (srcpkg[0] != 0) { if (!create_pkg_path(dstpath, PKG_DIR_PREFIX, dstpkg, PKG_DIR_POSTFIX)) { if (!create_pkg_path(dstpath, dstpkg, PKG_DIR_POSTFIX, 0)) { if (lstat(dstpath, &s) == 0) { dstuid = s.st_uid; dstgid = s.st_gid; Loading
cmds/installd/installd.c +66 −2 Original line number Diff line number Diff line Loading @@ -21,7 +21,6 @@ #define TOKEN_MAX 8 /* max number of arguments in buffer */ #define REPLY_MAX 256 /* largest reply allowed */ static int do_ping(char **arg, char reply[REPLY_MAX]) { return 0; Loading Loading @@ -235,12 +234,77 @@ done: return 0; } /** * Initialize all the global variables that are used elsewhere. Returns 0 upon * success and -1 on error. */ void free_globals() { size_t i; for (i = 0; i < android_system_dirs.count; i++) { if (android_system_dirs.dirs[i].path != NULL) { free(android_system_dirs.dirs[i].path); } } free(android_system_dirs.dirs); } int initialize_globals() { // Get the android data directory. if (get_path_from_env(&android_data_dir, "ANDROID_DATA") < 0) { return -1; } // Get the android app directory. if (copy_and_append(&android_app_dir, &android_data_dir, APP_SUBDIR) < 0) { return -1; } // Get the android protected app directory. if (copy_and_append(&android_app_private_dir, &android_data_dir, PRIVATE_APP_SUBDIR) < 0) { return -1; } // Get the sd-card ASEC mount point. if (get_path_from_env(&android_asec_dir, "ASEC_MOUNTPOINT") < 0) { return -1; } // Take note of the system and vendor directories. android_system_dirs.count = 2; android_system_dirs.dirs = calloc(android_system_dirs.count, sizeof(dir_rec_t)); if (android_system_dirs.dirs == NULL) { LOGE("Couldn't allocate array for dirs; aborting\n"); return -1; } // system if (get_path_from_env(&android_system_dirs.dirs[0], "ANDROID_ROOT") < 0) { free_globals(); return -1; } // vendor // TODO replace this with an environment variable (doesn't exist yet) android_system_dirs.dirs[1].path = "/vendor/"; android_system_dirs.dirs[1].len = strlen(android_system_dirs.dirs[1].path); return 0; } int main(const int argc, const char *argv[]) { char buf[BUFFER_MAX]; struct sockaddr addr; socklen_t alen; int lsocket, s, count; if (initialize_globals() < 0) { LOGE("Could not initialize globals; exiting.\n"); exit(1); } lsocket = android_get_control_socket(SOCKET_PATH); if (lsocket < 0) { LOGE("Failed to get socket from environment: %s\n", strerror(errno)); Loading
cmds/installd/installd.h +45 −10 Original line number Diff line number Diff line Loading @@ -49,21 +49,20 @@ /* elements combined with a valid package name to form paths */ #define PKG_DIR_PREFIX "/data/data/" #define PRIMARY_USER_PREFIX "data/" #define SECONDARY_USER_PREFIX "user/" #define PKG_DIR_POSTFIX "" #define PKG_LIB_PREFIX "/data/data/" #define PKG_LIB_POSTFIX "/lib" #define CACHE_DIR_PREFIX "/data/data/" #define CACHE_DIR_POSTFIX "/cache" #define APK_DIR_PREFIX "/data/app/" #define APP_SUBDIR "app/" // sub-directory under ANDROID_DATA /* other handy constants */ #define PROTECTED_DIR_PREFIX "/data/app-private/" #define SDCARD_DIR_PREFIX getenv("ASEC_MOUNTPOINT") #define PRIVATE_APP_SUBDIR "app-private/" // sub-directory under ANDROID_DATA #define DALVIK_CACHE_PREFIX "/data/dalvik-cache/" #define DALVIK_CACHE_POSTFIX "/classes.dex" Loading @@ -73,14 +72,38 @@ #define PKG_NAME_MAX 128 /* largest allowed package name */ #define PKG_PATH_MAX 256 /* max size of any path we use */ /* data structures */ typedef struct { char* path; size_t len; } dir_rec_t; typedef struct { size_t count; dir_rec_t* dirs; } dir_rec_array_t; extern dir_rec_t android_app_dir; extern dir_rec_t android_app_private_dir; extern dir_rec_t android_data_dir; extern dir_rec_t android_asec_dir; extern dir_rec_array_t android_system_dirs; /* util.c */ int create_pkg_path(char path[PKG_PATH_MAX], const char *prefix, int create_pkg_path_in_dir(char path[PKG_PATH_MAX], const dir_rec_t* dir, const char* pkgname, const char* postfix); int create_pkg_path(char path[PKG_PATH_MAX], const char *pkgname, const char *postfix, uid_t persona); int is_valid_package_name(const char* pkgname); int create_cache_path(char path[PKG_PATH_MAX], const char *src); int delete_dir_contents(const char *pathname, Loading @@ -89,6 +112,18 @@ int delete_dir_contents(const char *pathname, int delete_dir_contents_fd(int dfd, const char *name); int validate_system_app_path(const char* path); int get_path_from_env(dir_rec_t* rec, const char* var); int get_path_from_string(dir_rec_t* rec, const char* path); int copy_and_append(dir_rec_t* dst, const dir_rec_t* src, const char* suffix); int validate_apk_path(const char *path); int append_and_increment(char** dst, const char* src, size_t* dst_size); /* commands.c */ int install(const char *pkgname, uid_t uid, gid_t gid); Loading
cmds/installd/tests/Android.mk 0 → 100644 +42 −0 Original line number Diff line number Diff line # Build the unit tests for installd LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) ifneq ($(TARGET_SIMULATOR),true) # Build the unit tests. test_src_files := \ installd_utils_test.cpp shared_libraries := \ libutils \ libcutils \ libstlport static_libraries := \ libinstalld \ libdiskusage \ libgtest \ libgtest_main c_includes := \ frameworks/base/cmds/installd \ bionic \ bionic/libstdc++/include \ external/gtest/include \ external/stlport/stlport module_tags := eng tests $(foreach file,$(test_src_files), \ $(eval include $(CLEAR_VARS)) \ $(eval LOCAL_SHARED_LIBRARIES := $(shared_libraries)) \ $(eval LOCAL_STATIC_LIBRARIES := $(static_libraries)) \ $(eval LOCAL_SRC_FILES := $(file)) \ $(eval LOCAL_C_INCLUDES := $(c_includes)) \ $(eval LOCAL_MODULE := $(notdir $(file:%.cpp=%))) \ $(eval LOCAL_MODULE_TAGS := $(module_tags)) \ $(eval include $(BUILD_EXECUTABLE)) \ ) endif