Loading cmds/installd/installd.c +42 −33 Original line number Diff line number Diff line Loading @@ -511,14 +511,20 @@ int initialize_directories() { if (version == 2) { ALOGD("Upgrading to /data/misc/user directories"); char misc_dir[PATH_MAX]; snprintf(misc_dir, PATH_MAX, "%smisc", android_data_dir.path); char keychain_added_dir[PATH_MAX]; snprintf(keychain_added_dir, PATH_MAX, "%s/keychain/cacerts-added", misc_dir); char keychain_removed_dir[PATH_MAX]; snprintf(keychain_removed_dir, PATH_MAX, "%s/keychain/cacerts-removed", misc_dir); DIR *dir; struct dirent *dirent; char user_data_dir[PATH_MAX]; dir = opendir(user_data_dir); if (dir != NULL) { while ((dirent = readdir(dir))) { if (dirent->d_type == DT_DIR) { const char *name = dirent->d_name; // skip "." and ".." Loading @@ -527,36 +533,39 @@ int initialize_directories() { if ((name[1] == '.') && (name[2] == 0)) continue; } uint32_t user_id = atoi(name); // /data/misc/user/<user_id> if (ensure_config_user_dirs(atoi(name)) == -1) { if (ensure_config_user_dirs(user_id) == -1) { goto fail; } } } closedir(dir); } // Just rename keychain files into user/0; they should already have the right permissions char misc_dir[PATH_MAX]; char keychain_added_dir[PATH_MAX]; char keychain_removed_dir[PATH_MAX]; char config_added_dir[PATH_MAX]; char config_removed_dir[PATH_MAX]; char misc_added_dir[PATH_MAX]; snprintf(misc_added_dir, PATH_MAX, "%s/user/%s/cacerts-added", misc_dir, name); snprintf(misc_dir, PATH_MAX, "%s/misc", android_data_dir.path); snprintf(keychain_added_dir, PATH_MAX, "%s/keychain/cacerts-added", misc_dir); snprintf(keychain_removed_dir, PATH_MAX, "%s/keychain/cacerts-removed", misc_dir); snprintf(config_added_dir, PATH_MAX, "%s/user/0/cacerts-added", misc_dir); snprintf(config_removed_dir, PATH_MAX, "%s/user/0/cacerts-removed", misc_dir); char misc_removed_dir[PATH_MAX]; snprintf(misc_removed_dir, PATH_MAX, "%s/user/%s/cacerts-removed", misc_dir, name); uid_t uid = multiuser_get_uid(user_id, AID_SYSTEM); gid_t gid = uid; if (access(keychain_added_dir, F_OK) == 0) { if (rename(keychain_added_dir, config_added_dir) != 0) { goto fail; if (copy_dir_files(keychain_added_dir, misc_added_dir, uid, gid) != 0) { ALOGE("Some files failed to copy"); } } if (access(keychain_removed_dir, F_OK) == 0) { if (rename(keychain_removed_dir, config_removed_dir) != 0) { goto fail; if (copy_dir_files(keychain_removed_dir, misc_removed_dir, uid, gid) != 0) { ALOGE("Some files failed to copy"); } } } closedir(dir); if (access(keychain_added_dir, F_OK) == 0) { delete_dir_contents(keychain_added_dir, 1, 0); } if (access(keychain_removed_dir, F_OK) == 0) { delete_dir_contents(keychain_removed_dir, 1, 0); } } Loading cmds/installd/installd.h +2 −0 Original line number Diff line number Diff line Loading @@ -165,6 +165,8 @@ int delete_dir_contents(const char *pathname, int delete_dir_contents_fd(int dfd, const char *name); int copy_dir_files(const char *srcname, const char *dstname, uid_t owner, gid_t group); int lookup_media_dir(char basepath[PATH_MAX], const char *dir); int64_t data_disk_free(); Loading cmds/installd/utils.c +100 −2 Original line number Diff line number Diff line Loading @@ -324,6 +324,104 @@ int delete_dir_contents_fd(int dfd, const char *name) return res; } static int _copy_owner_permissions(int srcfd, int dstfd) { struct stat st; if (fstat(srcfd, &st) != 0) { return -1; } if (fchmod(dstfd, st.st_mode) != 0) { return -1; } return 0; } static int _copy_dir_files(int sdfd, int ddfd, uid_t owner, gid_t group) { int result = 0; if (_copy_owner_permissions(sdfd, ddfd) != 0) { ALOGE("_copy_dir_files failed to copy dir permissions\n"); } if (fchown(ddfd, owner, group) != 0) { ALOGE("_copy_dir_files failed to change dir owner\n"); } DIR *ds = fdopendir(sdfd); if (ds == NULL) { ALOGE("Couldn't fdopendir: %s\n", strerror(errno)); return -1; } struct dirent *de; while ((de = readdir(ds))) { if (de->d_type != DT_REG) { continue; } const char *name = de->d_name; int fsfd = openat(sdfd, name, O_RDONLY | O_NOFOLLOW | O_CLOEXEC); int fdfd = openat(ddfd, name, O_WRONLY | O_NOFOLLOW | O_CLOEXEC | O_CREAT, 0600); if (fsfd == -1 || fdfd == -1) { ALOGW("Couldn't copy %s: %s\n", name, strerror(errno)); } else { if (_copy_owner_permissions(fsfd, fdfd) != 0) { ALOGE("Failed to change file permissions\n"); } if (fchown(fdfd, owner, group) != 0) { ALOGE("Failed to change file owner\n"); } char buf[8192]; ssize_t size; while ((size = read(fsfd, buf, sizeof(buf))) > 0) { write(fdfd, buf, size); } if (size < 0) { ALOGW("Couldn't copy %s: %s\n", name, strerror(errno)); result = -1; } } close(fdfd); close(fsfd); } return result; } int copy_dir_files(const char *srcname, const char *dstname, uid_t owner, uid_t group) { int res = 0; DIR *ds = NULL; DIR *dd = NULL; ds = opendir(srcname); if (ds == NULL) { ALOGE("Couldn't opendir %s: %s\n", srcname, strerror(errno)); return -errno; } mkdir(dstname, 0600); dd = opendir(dstname); if (dd == NULL) { ALOGE("Couldn't opendir %s: %s\n", dstname, strerror(errno)); closedir(ds); return -errno; } int sdfd = dirfd(ds); int ddfd = dirfd(dd); if (sdfd != -1 && ddfd != -1) { res = _copy_dir_files(sdfd, ddfd, owner, group); } else { res = -errno; } closedir(dd); closedir(ds); return res; } int lookup_media_dir(char basepath[PATH_MAX], const char *dir) { DIR *d; Loading Loading @@ -1019,8 +1117,8 @@ int ensure_config_user_dirs(userid_t userid) { char path[PATH_MAX]; // writable by system, readable by any app within the same user const int uid = (userid * AID_USER) + AID_SYSTEM; const int gid = (userid * AID_USER) + AID_EVERYBODY; const int uid = multiuser_get_uid(userid, AID_SYSTEM); const int gid = multiuser_get_uid(userid, AID_EVERYBODY); // Ensure /data/misc/user/<userid> exists create_user_config_path(config_user_path, userid); Loading Loading
cmds/installd/installd.c +42 −33 Original line number Diff line number Diff line Loading @@ -511,14 +511,20 @@ int initialize_directories() { if (version == 2) { ALOGD("Upgrading to /data/misc/user directories"); char misc_dir[PATH_MAX]; snprintf(misc_dir, PATH_MAX, "%smisc", android_data_dir.path); char keychain_added_dir[PATH_MAX]; snprintf(keychain_added_dir, PATH_MAX, "%s/keychain/cacerts-added", misc_dir); char keychain_removed_dir[PATH_MAX]; snprintf(keychain_removed_dir, PATH_MAX, "%s/keychain/cacerts-removed", misc_dir); DIR *dir; struct dirent *dirent; char user_data_dir[PATH_MAX]; dir = opendir(user_data_dir); if (dir != NULL) { while ((dirent = readdir(dir))) { if (dirent->d_type == DT_DIR) { const char *name = dirent->d_name; // skip "." and ".." Loading @@ -527,36 +533,39 @@ int initialize_directories() { if ((name[1] == '.') && (name[2] == 0)) continue; } uint32_t user_id = atoi(name); // /data/misc/user/<user_id> if (ensure_config_user_dirs(atoi(name)) == -1) { if (ensure_config_user_dirs(user_id) == -1) { goto fail; } } } closedir(dir); } // Just rename keychain files into user/0; they should already have the right permissions char misc_dir[PATH_MAX]; char keychain_added_dir[PATH_MAX]; char keychain_removed_dir[PATH_MAX]; char config_added_dir[PATH_MAX]; char config_removed_dir[PATH_MAX]; char misc_added_dir[PATH_MAX]; snprintf(misc_added_dir, PATH_MAX, "%s/user/%s/cacerts-added", misc_dir, name); snprintf(misc_dir, PATH_MAX, "%s/misc", android_data_dir.path); snprintf(keychain_added_dir, PATH_MAX, "%s/keychain/cacerts-added", misc_dir); snprintf(keychain_removed_dir, PATH_MAX, "%s/keychain/cacerts-removed", misc_dir); snprintf(config_added_dir, PATH_MAX, "%s/user/0/cacerts-added", misc_dir); snprintf(config_removed_dir, PATH_MAX, "%s/user/0/cacerts-removed", misc_dir); char misc_removed_dir[PATH_MAX]; snprintf(misc_removed_dir, PATH_MAX, "%s/user/%s/cacerts-removed", misc_dir, name); uid_t uid = multiuser_get_uid(user_id, AID_SYSTEM); gid_t gid = uid; if (access(keychain_added_dir, F_OK) == 0) { if (rename(keychain_added_dir, config_added_dir) != 0) { goto fail; if (copy_dir_files(keychain_added_dir, misc_added_dir, uid, gid) != 0) { ALOGE("Some files failed to copy"); } } if (access(keychain_removed_dir, F_OK) == 0) { if (rename(keychain_removed_dir, config_removed_dir) != 0) { goto fail; if (copy_dir_files(keychain_removed_dir, misc_removed_dir, uid, gid) != 0) { ALOGE("Some files failed to copy"); } } } closedir(dir); if (access(keychain_added_dir, F_OK) == 0) { delete_dir_contents(keychain_added_dir, 1, 0); } if (access(keychain_removed_dir, F_OK) == 0) { delete_dir_contents(keychain_removed_dir, 1, 0); } } Loading
cmds/installd/installd.h +2 −0 Original line number Diff line number Diff line Loading @@ -165,6 +165,8 @@ int delete_dir_contents(const char *pathname, int delete_dir_contents_fd(int dfd, const char *name); int copy_dir_files(const char *srcname, const char *dstname, uid_t owner, gid_t group); int lookup_media_dir(char basepath[PATH_MAX], const char *dir); int64_t data_disk_free(); Loading
cmds/installd/utils.c +100 −2 Original line number Diff line number Diff line Loading @@ -324,6 +324,104 @@ int delete_dir_contents_fd(int dfd, const char *name) return res; } static int _copy_owner_permissions(int srcfd, int dstfd) { struct stat st; if (fstat(srcfd, &st) != 0) { return -1; } if (fchmod(dstfd, st.st_mode) != 0) { return -1; } return 0; } static int _copy_dir_files(int sdfd, int ddfd, uid_t owner, gid_t group) { int result = 0; if (_copy_owner_permissions(sdfd, ddfd) != 0) { ALOGE("_copy_dir_files failed to copy dir permissions\n"); } if (fchown(ddfd, owner, group) != 0) { ALOGE("_copy_dir_files failed to change dir owner\n"); } DIR *ds = fdopendir(sdfd); if (ds == NULL) { ALOGE("Couldn't fdopendir: %s\n", strerror(errno)); return -1; } struct dirent *de; while ((de = readdir(ds))) { if (de->d_type != DT_REG) { continue; } const char *name = de->d_name; int fsfd = openat(sdfd, name, O_RDONLY | O_NOFOLLOW | O_CLOEXEC); int fdfd = openat(ddfd, name, O_WRONLY | O_NOFOLLOW | O_CLOEXEC | O_CREAT, 0600); if (fsfd == -1 || fdfd == -1) { ALOGW("Couldn't copy %s: %s\n", name, strerror(errno)); } else { if (_copy_owner_permissions(fsfd, fdfd) != 0) { ALOGE("Failed to change file permissions\n"); } if (fchown(fdfd, owner, group) != 0) { ALOGE("Failed to change file owner\n"); } char buf[8192]; ssize_t size; while ((size = read(fsfd, buf, sizeof(buf))) > 0) { write(fdfd, buf, size); } if (size < 0) { ALOGW("Couldn't copy %s: %s\n", name, strerror(errno)); result = -1; } } close(fdfd); close(fsfd); } return result; } int copy_dir_files(const char *srcname, const char *dstname, uid_t owner, uid_t group) { int res = 0; DIR *ds = NULL; DIR *dd = NULL; ds = opendir(srcname); if (ds == NULL) { ALOGE("Couldn't opendir %s: %s\n", srcname, strerror(errno)); return -errno; } mkdir(dstname, 0600); dd = opendir(dstname); if (dd == NULL) { ALOGE("Couldn't opendir %s: %s\n", dstname, strerror(errno)); closedir(ds); return -errno; } int sdfd = dirfd(ds); int ddfd = dirfd(dd); if (sdfd != -1 && ddfd != -1) { res = _copy_dir_files(sdfd, ddfd, owner, group); } else { res = -errno; } closedir(dd); closedir(ds); return res; } int lookup_media_dir(char basepath[PATH_MAX], const char *dir) { DIR *d; Loading Loading @@ -1019,8 +1117,8 @@ int ensure_config_user_dirs(userid_t userid) { char path[PATH_MAX]; // writable by system, readable by any app within the same user const int uid = (userid * AID_USER) + AID_SYSTEM; const int gid = (userid * AID_USER) + AID_EVERYBODY; const int uid = multiuser_get_uid(userid, AID_SYSTEM); const int gid = multiuser_get_uid(userid, AID_EVERYBODY); // Ensure /data/misc/user/<userid> exists create_user_config_path(config_user_path, userid); Loading