Merge "More device-encrypted directory work."
diff --git a/cmds/installd/commands.cpp b/cmds/installd/commands.cpp
index 09c74b2..e050d0f 100644
--- a/cmds/installd/commands.cpp
+++ b/cmds/installd/commands.cpp
@@ -49,46 +49,17 @@
return -1;
}
- std::string ce_package_path(create_data_user_package_path(uuid, 0, pkgname));
- std::string de_package_path(create_data_user_de_package_path(uuid, 0, pkgname));
-
- const char* c_ce_package_path = ce_package_path.c_str();
- const char* c_de_package_path = de_package_path.c_str();
-
- if (fs_prepare_dir(c_ce_package_path, 0751, uid, gid) == -1) {
- PLOG(ERROR) << "Failed to prepare " << ce_package_path;
- unlink(c_ce_package_path);
- return -1;
- }
- if (selinux_android_setfilecon(c_ce_package_path, pkgname, seinfo, uid) < 0) {
- PLOG(ERROR) << "Failed to setfilecon " << ce_package_path;
- unlink(c_ce_package_path);
- return -1;
- }
-
- if (property_get_bool("vold.has_fbe", false)) {
- if (fs_prepare_dir(c_de_package_path, 0751, uid, gid) == -1) {
- PLOG(ERROR) << "Failed to prepare " << de_package_path;
- unlink(c_de_package_path);
- return -1;
- }
- if (selinux_android_setfilecon(c_de_package_path, pkgname, seinfo, uid) < 0) {
- PLOG(ERROR) << "Failed to setfilecon " << de_package_path;
- unlink(c_de_package_path);
- return -1;
- }
- }
-
- return 0;
+ return make_user_data(uuid, pkgname, uid, 0, seinfo);
}
-int uninstall(const char *uuid, const char *pkgname, userid_t userid)
-{
- std::string _pkgdir(create_data_user_package_path(uuid, userid, pkgname));
- const char* pkgdir = _pkgdir.c_str();
+int uninstall(const char *uuid, const char *pkgname, userid_t userid) {
+ std::string ce_package_path(create_data_user_package_path(uuid, userid, pkgname));
+ std::string de_package_path(create_data_user_de_package_path(uuid, userid, pkgname));
- /* delete contents AND directory, no exceptions */
- return delete_dir_contents(pkgdir, 1, NULL);
+ int res = 0;
+ res |= delete_dir_contents_and_dir(ce_package_path);
+ res |= delete_dir_contents_and_dir(de_package_path);
+ return res;
}
int fix_uid(const char *uuid, const char *pkgname, uid_t uid, gid_t gid)
@@ -100,6 +71,7 @@
return -1;
}
+ // TODO: handle user_de paths
std::string _pkgdir(create_data_user_package_path(uuid, 0, pkgname));
const char* pkgdir = _pkgdir.c_str();
@@ -124,39 +96,44 @@
return 0;
}
-int delete_user_data(const char *uuid, const char *pkgname, userid_t userid)
-{
- std::string _pkgdir(create_data_user_package_path(uuid, userid, pkgname));
- const char* pkgdir = _pkgdir.c_str();
+int delete_user_data(const char *uuid, const char *pkgname, userid_t userid) {
+ std::string ce_package_path(create_data_user_package_path(uuid, userid, pkgname));
+ std::string de_package_path(create_data_user_de_package_path(uuid, userid, pkgname));
- return delete_dir_contents(pkgdir, 0, NULL);
+ int res = 0;
+ res |= delete_dir_contents(ce_package_path);
+ res |= delete_dir_contents(de_package_path);
+ return res;
}
-int make_user_data(const char *uuid, const char *pkgname, uid_t uid, userid_t userid, const char* seinfo)
-{
- std::string _pkgdir(create_data_user_package_path(uuid, userid, pkgname));
- const char* pkgdir = _pkgdir.c_str();
+int make_user_data(const char *uuid, const char *pkgname, uid_t uid, userid_t userid,
+ const char* seinfo) {
+ std::string ce_package_path(create_data_user_package_path(uuid, userid, pkgname));
+ std::string de_package_path(create_data_user_de_package_path(uuid, userid, pkgname));
- if (mkdir(pkgdir, 0751) < 0) {
- ALOGE("cannot create dir '%s': %s\n", pkgdir, strerror(errno));
- return -errno;
+ const char* c_ce_package_path = ce_package_path.c_str();
+ const char* c_de_package_path = de_package_path.c_str();
+
+ if (fs_prepare_dir(c_ce_package_path, 0751, uid, uid) == -1) {
+ PLOG(ERROR) << "Failed to prepare " << ce_package_path;
+ unlink(c_ce_package_path);
+ return -1;
}
- if (chmod(pkgdir, 0751) < 0) {
- ALOGE("cannot chmod dir '%s': %s\n", pkgdir, strerror(errno));
- unlink(pkgdir);
- return -errno;
+ if (selinux_android_setfilecon(c_ce_package_path, pkgname, seinfo, uid) < 0) {
+ PLOG(ERROR) << "Failed to setfilecon " << ce_package_path;
+ unlink(c_ce_package_path);
+ return -1;
}
- if (selinux_android_setfilecon(pkgdir, pkgname, seinfo, uid) < 0) {
- ALOGE("cannot setfilecon dir '%s': %s\n", pkgdir, strerror(errno));
- unlink(pkgdir);
- return -errno;
+ if (fs_prepare_dir(c_de_package_path, 0751, uid, uid) == -1) {
+ PLOG(ERROR) << "Failed to prepare " << de_package_path;
+ unlink(c_de_package_path);
+ return -1;
}
-
- if (chown(pkgdir, uid, uid) < 0) {
- ALOGE("cannot chown dir '%s': %s\n", pkgdir, strerror(errno));
- unlink(pkgdir);
- return -errno;
+ if (selinux_android_setfilecon(c_de_package_path, pkgname, seinfo, uid) < 0) {
+ PLOG(ERROR) << "Failed to setfilecon " << de_package_path;
+ unlink(c_de_package_path);
+ return -1;
}
return 0;
@@ -200,6 +177,7 @@
}
// Copy private data for all known users
+ // TODO: handle user_de paths
for (auto user : users) {
std::string from(create_data_user_package_path(from_uuid, user, package_name));
std::string to(create_data_user_package_path(to_uuid, user, package_name));
@@ -280,30 +258,27 @@
return 0;
}
-int delete_user(const char *uuid, userid_t userid)
-{
- int status = 0;
+int delete_user(const char *uuid, userid_t userid) {
+ int res = 0;
std::string data_path(create_data_user_path(uuid, userid));
- if (delete_dir_contents(data_path.c_str(), 1, NULL) != 0) {
- status = -1;
- }
-
+ std::string data_de_path(create_data_user_de_path(uuid, userid));
std::string media_path(create_data_media_path(uuid, userid));
- if (delete_dir_contents(media_path.c_str(), 1, NULL) != 0) {
- status = -1;
- }
+
+ res |= delete_dir_contents_and_dir(data_path);
+ res |= delete_dir_contents_and_dir(data_de_path);
+ res |= delete_dir_contents_and_dir(media_path);
// Config paths only exist on internal storage
if (uuid == nullptr) {
char config_path[PATH_MAX];
if ((create_user_config_path(config_path, userid) != 0)
|| (delete_dir_contents(config_path, 1, NULL) != 0)) {
- status = -1;
+ res = -1;
}
}
- return status;
+ return res;
}
int delete_cache(const char *uuid, const char *pkgname, userid_t userid)
@@ -546,6 +521,7 @@
}
for (auto user : users) {
+ // TODO: handle user_de directories
std::string _pkgdir(create_data_user_package_path(uuid, user, pkgname));
const char* pkgdir = _pkgdir.c_str();
@@ -1681,13 +1657,8 @@
return -1;
}
-int restorecon_data(const char* uuid, const char* pkgName,
- const char* seinfo, uid_t uid)
-{
- struct dirent *entry;
- DIR *d;
- struct stat s;
- int ret = 0;
+int restorecon_data(const char* uuid, const char* pkgName, const char* seinfo, appid_t appid) {
+ int res = 0;
// SELINUX_ANDROID_RESTORECON_DATADATA flag is set by libselinux. Not needed here.
unsigned int flags = SELINUX_ANDROID_RESTORECON_RECURSE;
@@ -1697,53 +1668,25 @@
return -1;
}
- // Special case for owner on internal storage
- if (uuid == nullptr) {
- std::string path(create_data_user_package_path(nullptr, 0, pkgName));
+ // Relabel package directory for all users
+ std::vector<userid_t> users = get_known_users(uuid);
+ for (auto user : users) {
+ uid_t uid = multiuser_get_uid(user, appid);
- if (selinux_android_restorecon_pkgdir(path.c_str(), seinfo, uid, flags) < 0) {
- PLOG(ERROR) << "restorecon failed for " << path;
- ret |= -1;
+ std::string ce_package_path(create_data_user_package_path(uuid, user, pkgName));
+ std::string de_package_path(create_data_user_de_package_path(uuid, user, pkgName));
+
+ if (selinux_android_restorecon_pkgdir(ce_package_path.c_str(), seinfo, uid, flags) < 0) {
+ PLOG(ERROR) << "restorecon failed for " << ce_package_path;
+ res = -1;
+ }
+ if (selinux_android_restorecon_pkgdir(de_package_path.c_str(), seinfo, uid, flags) < 0) {
+ PLOG(ERROR) << "restorecon failed for " << de_package_path;
+ res = -1;
}
}
- // Relabel package directory for all secondary users.
- std::string userdir(create_data_path(uuid) + "/" + SECONDARY_USER_PREFIX);
- d = opendir(userdir.c_str());
- if (d == NULL) {
- return -1;
- }
-
- while ((entry = readdir(d))) {
- if (entry->d_type != DT_DIR) {
- continue;
- }
-
- const char *user = entry->d_name;
- // Ignore "." and ".."
- if (!strcmp(user, ".") || !strcmp(user, "..")) {
- continue;
- }
-
- // user directories start with a number
- if (user[0] < '0' || user[0] > '9') {
- ALOGE("Expecting numbered directory during restorecon. Instead got '%s'.", user);
- continue;
- }
-
- std::string pkgdir(StringPrintf("%s%s/%s", userdir.c_str(), user, pkgName));
- if (stat(pkgdir.c_str(), &s) < 0) {
- continue;
- }
-
- if (selinux_android_restorecon_pkgdir(pkgdir.c_str(), seinfo, s.st_uid, flags) < 0) {
- PLOG(ERROR) << "restorecon failed for " << pkgdir;
- ret |= -1;
- }
- }
-
- closedir(d);
- return ret;
+ return res;
}
int create_oat_dir(const char* oat_dir, const char* instruction_set)
diff --git a/cmds/installd/installd.h b/cmds/installd/installd.h
index 5709da6..d911c49 100644
--- a/cmds/installd/installd.h
+++ b/cmds/installd/installd.h
@@ -196,6 +196,9 @@
int create_cache_path(char path[PKG_PATH_MAX], const char *src,
const char *instruction_set);
+int delete_dir_contents(const std::string& pathname);
+int delete_dir_contents_and_dir(const std::string& pathname);
+
int delete_dir_contents(const char *pathname,
int also_delete_dir,
int (*exclusion_predicate)(const char *name, const int is_dir));
diff --git a/cmds/installd/utils.cpp b/cmds/installd/utils.cpp
index bd09d92..549a420 100644
--- a/cmds/installd/utils.cpp
+++ b/cmds/installd/utils.cpp
@@ -305,6 +305,14 @@
return result;
}
+int delete_dir_contents(const std::string& pathname) {
+ return delete_dir_contents(pathname.c_str(), 0, NULL);
+}
+
+int delete_dir_contents_and_dir(const std::string& pathname) {
+ return delete_dir_contents(pathname.c_str(), 1, NULL);
+}
+
int delete_dir_contents(const char *pathname,
int also_delete_dir,
int (*exclusion_predicate)(const char*, const int))