Merge "Pass through availability of audio mic for input devices."
diff --git a/cmds/installd/Android.mk b/cmds/installd/Android.mk
index 2d90ff3..c664148 100644
--- a/cmds/installd/Android.mk
+++ b/cmds/installd/Android.mk
@@ -12,6 +12,7 @@
LOCAL_MODULE_TAGS := eng tests
LOCAL_SRC_FILES := $(common_src_files)
LOCAL_CFLAGS := $(common_cflags)
+LOCAL_SHARED_LIBRARIES := libbase
LOCAL_ADDITIONAL_DEPENDENCIES += $(LOCAL_PATH)/Android.mk
include $(BUILD_STATIC_LIBRARY)
@@ -24,7 +25,12 @@
LOCAL_MODULE_TAGS := optional
LOCAL_CFLAGS := $(common_cflags)
LOCAL_SRC_FILES := installd.cpp $(common_src_files)
-LOCAL_SHARED_LIBRARIES := libcutils liblog libselinux
+LOCAL_SHARED_LIBRARIES := \
+ libbase \
+ libcutils \
+ liblog \
+ libselinux \
+
LOCAL_STATIC_LIBRARIES := libdiskusage
LOCAL_ADDITIONAL_DEPENDENCIES += $(LOCAL_PATH)/Android.mk
include $(BUILD_EXECUTABLE)
diff --git a/cmds/installd/commands.cpp b/cmds/installd/commands.cpp
index 5f72ae4..73f707a 100644
--- a/cmds/installd/commands.cpp
+++ b/cmds/installd/commands.cpp
@@ -33,11 +33,8 @@
dir_rec_t android_mnt_expand_dir;
dir_rec_array_t android_system_dirs;
-int install(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)
{
- char pkgdir[PKG_PATH_MAX];
- char libsymlink[PKG_PATH_MAX];
- char applibdir[PKG_PATH_MAX];
struct stat libStat;
if ((uid < AID_SYSTEM) || (gid < AID_SYSTEM)) {
@@ -45,20 +42,8 @@
return -1;
}
- if (create_pkg_path(pkgdir, pkgname, PKG_DIR_POSTFIX, 0)) {
- ALOGE("cannot create package path\n");
- return -1;
- }
-
- if (create_pkg_path(libsymlink, pkgname, PKG_LIB_POSTFIX, 0)) {
- ALOGE("cannot create package lib symlink origin path\n");
- return -1;
- }
-
- if (create_pkg_path_in_dir(applibdir, &android_app_lib_dir, pkgname, PKG_DIR_POSTFIX)) {
- ALOGE("cannot create package lib symlink dest path\n");
- return -1;
- }
+ std::string _pkgdir(create_package_data_path(uuid, pkgname, 0));
+ const char* pkgdir = _pkgdir.c_str();
if (mkdir(pkgdir, 0751) < 0) {
ALOGE("cannot create dir '%s': %s\n", pkgdir, strerror(errno));
@@ -70,42 +55,14 @@
return -1;
}
- if (lstat(libsymlink, &libStat) < 0) {
- if (errno != ENOENT) {
- ALOGE("couldn't stat lib dir: %s\n", strerror(errno));
- return -1;
- }
- } else {
- if (S_ISDIR(libStat.st_mode)) {
- if (delete_dir_contents(libsymlink, 1, NULL) < 0) {
- ALOGE("couldn't delete lib directory during install for: %s", libsymlink);
- return -1;
- }
- } else if (S_ISLNK(libStat.st_mode)) {
- if (unlink(libsymlink) < 0) {
- ALOGE("couldn't unlink lib directory during install for: %s", libsymlink);
- return -1;
- }
- }
- }
-
if (selinux_android_setfilecon(pkgdir, pkgname, seinfo, uid) < 0) {
ALOGE("cannot setfilecon dir '%s': %s\n", pkgdir, strerror(errno));
- unlink(libsymlink);
unlink(pkgdir);
return -errno;
}
- if (symlink(applibdir, libsymlink) < 0) {
- ALOGE("couldn't symlink directory '%s' -> '%s': %s\n", libsymlink, applibdir,
- strerror(errno));
- unlink(pkgdir);
- return -1;
- }
-
if (chown(pkgdir, uid, gid) < 0) {
ALOGE("cannot chown dir '%s': %s\n", pkgdir, strerror(errno));
- unlink(libsymlink);
unlink(pkgdir);
return -1;
}
@@ -113,12 +70,10 @@
return 0;
}
-int uninstall(const char *pkgname, userid_t userid)
+int uninstall(const char *uuid, const char *pkgname, userid_t userid)
{
- char pkgdir[PKG_PATH_MAX];
-
- if (create_pkg_path(pkgdir, pkgname, PKG_DIR_POSTFIX, userid))
- return -1;
+ std::string _pkgdir(create_package_data_path(uuid, pkgname, userid));
+ const char* pkgdir = _pkgdir.c_str();
remove_profile_file(pkgname);
@@ -143,9 +98,8 @@
return 0;
}
-int fix_uid(const char *pkgname, uid_t uid, gid_t gid)
+int fix_uid(const char *uuid, const char *pkgname, uid_t uid, gid_t gid)
{
- char pkgdir[PKG_PATH_MAX];
struct stat s;
if ((uid < AID_SYSTEM) || (gid < AID_SYSTEM)) {
@@ -153,10 +107,8 @@
return -1;
}
- if (create_pkg_path(pkgdir, pkgname, PKG_DIR_POSTFIX, 0)) {
- ALOGE("cannot create package path\n");
- return -1;
- }
+ std::string _pkgdir(create_package_data_path(uuid, pkgname, 0));
+ const char* pkgdir = _pkgdir.c_str();
if (stat(pkgdir, &s) < 0) return -1;
@@ -179,35 +131,20 @@
return 0;
}
-int delete_user_data(const char *pkgname, userid_t userid)
+int delete_user_data(const char *uuid, const char *pkgname, userid_t userid)
{
- char pkgdir[PKG_PATH_MAX];
-
- if (create_pkg_path(pkgdir, pkgname, PKG_DIR_POSTFIX, userid))
- return -1;
+ std::string _pkgdir(create_package_data_path(uuid, pkgname, userid));
+ const char* pkgdir = _pkgdir.c_str();
return delete_dir_contents(pkgdir, 0, NULL);
}
-int make_user_data(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)
{
- char pkgdir[PKG_PATH_MAX];
- char applibdir[PKG_PATH_MAX];
- char libsymlink[PKG_PATH_MAX];
struct stat libStat;
- // Create the data dir for the package
- if (create_pkg_path(pkgdir, pkgname, PKG_DIR_POSTFIX, userid)) {
- return -1;
- }
- if (create_pkg_path(libsymlink, pkgname, PKG_LIB_POSTFIX, userid)) {
- ALOGE("cannot create package lib symlink origin path\n");
- return -1;
- }
- if (create_pkg_path_in_dir(applibdir, &android_app_lib_dir, pkgname, PKG_DIR_POSTFIX)) {
- ALOGE("cannot create package lib symlink dest path\n");
- return -1;
- }
+ std::string _pkgdir(create_package_data_path(uuid, pkgname, userid));
+ const char* pkgdir = _pkgdir.c_str();
if (mkdir(pkgdir, 0751) < 0) {
ALOGE("cannot create dir '%s': %s\n", pkgdir, strerror(errno));
@@ -219,47 +156,14 @@
return -errno;
}
- if (lstat(libsymlink, &libStat) < 0) {
- if (errno != ENOENT) {
- ALOGE("couldn't stat lib dir for non-primary: %s\n", strerror(errno));
- unlink(pkgdir);
- return -1;
- }
- } else {
- if (S_ISDIR(libStat.st_mode)) {
- if (delete_dir_contents(libsymlink, 1, NULL) < 0) {
- ALOGE("couldn't delete lib directory during install for non-primary: %s",
- libsymlink);
- unlink(pkgdir);
- return -1;
- }
- } else if (S_ISLNK(libStat.st_mode)) {
- if (unlink(libsymlink) < 0) {
- ALOGE("couldn't unlink lib directory during install for non-primary: %s",
- libsymlink);
- unlink(pkgdir);
- return -1;
- }
- }
- }
-
if (selinux_android_setfilecon(pkgdir, pkgname, seinfo, uid) < 0) {
ALOGE("cannot setfilecon dir '%s': %s\n", pkgdir, strerror(errno));
- unlink(libsymlink);
unlink(pkgdir);
return -errno;
}
- if (symlink(applibdir, libsymlink) < 0) {
- ALOGE("couldn't symlink directory for non-primary '%s' -> '%s': %s\n", libsymlink,
- applibdir, strerror(errno));
- unlink(pkgdir);
- return -1;
- }
-
if (chown(pkgdir, uid, uid) < 0) {
ALOGE("cannot chown dir '%s': %s\n", pkgdir, strerror(errno));
- unlink(libsymlink);
unlink(pkgdir);
return -errno;
}
@@ -301,24 +205,23 @@
return status;
}
-int delete_cache(const char *pkgname, userid_t userid)
+int delete_cache(const char *uuid, const char *pkgname, userid_t userid)
{
- char cachedir[PKG_PATH_MAX];
-
- if (create_pkg_path(cachedir, pkgname, CACHE_DIR_POSTFIX, userid))
- return -1;
+ std::string _cachedir(
+ create_package_data_path(uuid, pkgname, userid) + CACHE_DIR_POSTFIX);
+ const char* cachedir = _cachedir.c_str();
/* delete contents, not the directory, no exceptions */
return delete_dir_contents(cachedir, 0, NULL);
}
-int delete_code_cache(const char *pkgname, userid_t userid)
+int delete_code_cache(const char *uuid, const char *pkgname, userid_t userid)
{
- char codecachedir[PKG_PATH_MAX];
- struct stat s;
+ std::string _codecachedir(
+ create_package_data_path(uuid, pkgname, userid) + CACHE_DIR_POSTFIX);
+ const char* codecachedir = _codecachedir.c_str();
- if (create_pkg_path(codecachedir, pkgname, CODE_CACHE_DIR_POSTFIX, userid))
- return -1;
+ struct stat s;
/* it's okay if code cache is missing */
if (lstat(codecachedir, &s) == -1 && errno == ENOENT) {
@@ -336,6 +239,7 @@
* also require that apps constantly modify file metadata even
* when just reading from the cache, which is pretty awful.
*/
+// TODO: extend to know about other volumes
int free_cache(int64_t free_size)
{
cache_t* cache;
@@ -467,7 +371,7 @@
}
}
-int get_size(const char *pkgname, userid_t userid, const char *apkpath,
+int get_size(const char *uuid, const char *pkgname, userid_t userid, const char *apkpath,
const char *libdirpath, const char *fwdlock_apkpath, const char *asecpath,
const char *instruction_set, int64_t *_codesize, int64_t *_datasize,
int64_t *_cachesize, int64_t* _asecsize)
@@ -524,11 +428,10 @@
}
}
- if (create_pkg_path(path, pkgname, PKG_DIR_POSTFIX, userid)) {
- goto done;
- }
+ std::string _pkgdir(create_package_data_path(uuid, pkgname, userid));
+ const char* pkgdir = _pkgdir.c_str();
- d = opendir(path);
+ d = opendir(pkgdir);
if (d == NULL) {
goto done;
}
@@ -988,8 +891,8 @@
}
int dexopt(const char *apk_path, uid_t uid, bool is_public,
- const char *pkgname, const char *instruction_set,
- bool vm_safe_mode, bool is_patchoat, bool debuggable, const char* oat_dir)
+ const char *pkgname, const char *instruction_set, int dexopt_needed,
+ bool vm_safe_mode, bool debuggable, const char* oat_dir)
{
struct utimbuf ut;
struct stat input_stat;
@@ -1021,13 +924,25 @@
}
}
- if (is_patchoat) {
- if (!calculate_odex_file_path(in_odex_path, apk_path, instruction_set)) {
- return -1;
- }
- input_file = in_odex_path;
- } else {
- input_file = apk_path;
+ switch (dexopt_needed) {
+ case DEXOPT_DEX2OAT_NEEDED:
+ input_file = apk_path;
+ break;
+
+ case DEXOPT_PATCHOAT_NEEDED:
+ if (!calculate_odex_file_path(in_odex_path, apk_path, instruction_set)) {
+ return -1;
+ }
+ input_file = in_odex_path;
+ break;
+
+ case DEXOPT_SELF_PATCHOAT_NEEDED:
+ input_file = out_path;
+ break;
+
+ default:
+ ALOGE("Invalid dexopt needed: %d\n", dexopt_needed);
+ exit(72);
}
memset(&input_stat, 0, sizeof(input_stat));
@@ -1062,7 +977,7 @@
}
// Create a swap file if necessary.
- if (!is_patchoat && ShouldUseSwapFileForDexopt()) {
+ if (ShouldUseSwapFileForDexopt()) {
// Make sure there really is enough space.
size_t out_len = strlen(out_path);
if (out_len + strlen(".swap") + 1 <= PKG_PATH_MAX) {
@@ -1121,9 +1036,10 @@
exit(67);
}
- if (is_patchoat) {
+ if (dexopt_needed == DEXOPT_PATCHOAT_NEEDED
+ || dexopt_needed == DEXOPT_SELF_PATCHOAT_NEEDED) {
run_patchoat(input_fd, out_fd, input_file, out_path, pkgname, instruction_set);
- } else {
+ } else if (dexopt_needed == DEXOPT_DEX2OAT_NEEDED) {
const char *input_file_name = strrchr(input_file, '/');
if (input_file_name == NULL) {
input_file_name = input_file;
@@ -1132,6 +1048,9 @@
}
run_dex2oat(input_fd, out_fd, input_file_name, out_path, swap_fd, pkgname,
instruction_set, vm_safe_mode, debuggable);
+ } else {
+ ALOGE("Invalid dexopt needed: %d\n", dexopt_needed);
+ exit(73);
}
exit(68); /* only get here on exec failure */
} else {
@@ -1441,21 +1360,16 @@
return 0;
}
-int linklib(const char* pkgname, const char* asecLibDir, int userId)
+int linklib(const char* uuid, const char* pkgname, const char* asecLibDir, int userId)
{
- char pkgdir[PKG_PATH_MAX];
- char libsymlink[PKG_PATH_MAX];
struct stat s, libStat;
int rc = 0;
- if (create_pkg_path(pkgdir, pkgname, PKG_DIR_POSTFIX, userId)) {
- ALOGE("cannot create package path\n");
- return -1;
- }
- if (create_pkg_path(libsymlink, pkgname, PKG_LIB_POSTFIX, userId)) {
- ALOGE("cannot create package lib symlink origin path\n");
- return -1;
- }
+ std::string _pkgdir(create_package_data_path(uuid, pkgname, userId));
+ std::string _libsymlink(_pkgdir + PKG_LIB_POSTFIX);
+
+ const char* pkgdir = _pkgdir.c_str();
+ const char* libsymlink = _libsymlink.c_str();
if (stat(pkgdir, &s) < 0) return -1;
@@ -1624,7 +1538,8 @@
return -1;
}
-int restorecon_data(const char* pkgName, const char* seinfo, uid_t uid)
+// TODO: extend to know about other volumes
+int restorecon_data(const char *uuid, const char* pkgName, const char* seinfo, uid_t uid)
{
struct dirent *entry;
DIR *d;
diff --git a/cmds/installd/installd.cpp b/cmds/installd/installd.cpp
index ad2478b..211b5b8 100644
--- a/cmds/installd/installd.cpp
+++ b/cmds/installd/installd.cpp
@@ -33,15 +33,15 @@
static int do_install(char **arg, char reply[REPLY_MAX] __unused)
{
- return install(arg[0], atoi(arg[1]), atoi(arg[2]), arg[3]); /* pkgname, uid, gid, seinfo */
+ return install(nullptr, arg[0], atoi(arg[1]), atoi(arg[2]), arg[3]); /* pkgname, uid, gid, seinfo */
}
static int do_dexopt(char **arg, char reply[REPLY_MAX] __unused)
{
- /* apk_path, uid, is_public, pkgname, instruction_set, vm_safe_mode, should_relocate
- debuggable, outputPath */
- return dexopt(arg[0], atoi(arg[1]), atoi(arg[2]), arg[3], arg[4], atoi(arg[5]), 0,
- atoi(arg[6]), arg[7]);
+ /* apk_path, uid, is_public, pkgname, instruction_set,
+ * dexopt_needed, vm_safe_mode, debuggable, oat_dir */
+ return dexopt(arg[0], atoi(arg[1]), atoi(arg[2]), arg[3], arg[4], atoi(arg[5]),
+ atoi(arg[6]), atoi(arg[7]), arg[8]);
}
static int do_mark_boot_complete(char **arg, char reply[REPLY_MAX] __unused)
@@ -61,7 +61,7 @@
static int do_remove(char **arg, char reply[REPLY_MAX] __unused)
{
- return uninstall(arg[0], atoi(arg[1])); /* pkgname, userid */
+ return uninstall(nullptr, arg[0], atoi(arg[1])); /* pkgname, userid */
}
static int do_rename(char **arg, char reply[REPLY_MAX] __unused)
@@ -71,7 +71,7 @@
static int do_fixuid(char **arg, char reply[REPLY_MAX] __unused)
{
- return fix_uid(arg[0], atoi(arg[1]), atoi(arg[2])); /* pkgname, uid, gid */
+ return fix_uid(nullptr, arg[0], atoi(arg[1]), atoi(arg[2])); /* pkgname, uid, gid */
}
static int do_free_cache(char **arg, char reply[REPLY_MAX] __unused) /* TODO int:free_size */
@@ -81,12 +81,12 @@
static int do_rm_cache(char **arg, char reply[REPLY_MAX] __unused)
{
- return delete_cache(arg[0], atoi(arg[1])); /* pkgname, userid */
+ return delete_cache(nullptr, arg[0], atoi(arg[1])); /* pkgname, userid */
}
static int do_rm_code_cache(char **arg, char reply[REPLY_MAX] __unused)
{
- return delete_code_cache(arg[0], atoi(arg[1])); /* pkgname, userid */
+ return delete_code_cache(nullptr, arg[0], atoi(arg[1])); /* pkgname, userid */
}
static int do_get_size(char **arg, char reply[REPLY_MAX])
@@ -98,7 +98,7 @@
int res = 0;
/* pkgdir, userid, apkpath */
- res = get_size(arg[0], atoi(arg[1]), arg[2], arg[3], arg[4], arg[5],
+ res = get_size(nullptr, arg[0], atoi(arg[1]), arg[2], arg[3], arg[4], arg[5],
arg[6], &codesize, &datasize, &cachesize, &asecsize);
/*
@@ -112,12 +112,12 @@
static int do_rm_user_data(char **arg, char reply[REPLY_MAX] __unused)
{
- return delete_user_data(arg[0], atoi(arg[1])); /* pkgname, userid */
+ return delete_user_data(nullptr, arg[0], atoi(arg[1])); /* pkgname, userid */
}
static int do_mk_user_data(char **arg, char reply[REPLY_MAX] __unused)
{
- return make_user_data(arg[0], atoi(arg[1]), atoi(arg[2]), arg[3]);
+ return make_user_data(nullptr, arg[0], atoi(arg[1]), atoi(arg[2]), arg[3]);
/* pkgname, uid, userid, seinfo */
}
@@ -138,7 +138,7 @@
static int do_linklib(char **arg, char reply[REPLY_MAX] __unused)
{
- return linklib(arg[0], arg[1], atoi(arg[2]));
+ return linklib(nullptr, arg[0], arg[1], atoi(arg[2]));
}
static int do_idmap(char **arg, char reply[REPLY_MAX] __unused)
@@ -148,16 +148,10 @@
static int do_restorecon_data(char **arg, char reply[REPLY_MAX] __attribute__((unused)))
{
- return restorecon_data(arg[0], arg[1], atoi(arg[2]));
+ return restorecon_data(nullptr, arg[0], arg[1], atoi(arg[2]));
/* pkgName, seinfo, uid*/
}
-static int do_patchoat(char **arg, char reply[REPLY_MAX] __unused) {
- /* apk_path, uid, is_public, pkgname, instruction_set, vm_safe_mode, should_relocate,
- debuggable, outputPath */
- return dexopt(arg[0], atoi(arg[1]), atoi(arg[2]), arg[3], arg[4], 0, 1, 0, "!");
-}
-
static int do_create_oat_dir(char **arg, char reply[REPLY_MAX] __unused)
{
/* oat_dir, instruction_set */
@@ -179,7 +173,7 @@
struct cmdinfo cmds[] = {
{ "ping", 0, do_ping },
{ "install", 4, do_install },
- { "dexopt", 8, do_dexopt },
+ { "dexopt", 9, do_dexopt },
{ "markbootcomplete", 1, do_mark_boot_complete },
{ "movedex", 3, do_move_dex },
{ "rmdex", 2, do_rm_dex },
@@ -198,7 +192,6 @@
{ "rmuser", 1, do_rm_user },
{ "idmap", 3, do_idmap },
{ "restorecondata", 3, do_restorecon_data },
- { "patchoat", 5, do_patchoat },
{ "createoatdir", 2, do_create_oat_dir },
{ "rmpackagedir", 1, do_rm_package_dir},
};
diff --git a/cmds/installd/installd.h b/cmds/installd/installd.h
index 0ebc0ba..4395941 100644
--- a/cmds/installd/installd.h
+++ b/cmds/installd/installd.h
@@ -31,6 +31,7 @@
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/wait.h>
+#include <string>
#include <cutils/fs.h>
#include <cutils/sockets.h>
@@ -83,6 +84,11 @@
#define PKG_NAME_MAX 128 /* largest allowed package name */
#define PKG_PATH_MAX 256 /* max size of any path we use */
+/* dexopt needed flags matching those in dalvik.system.DexFile */
+#define DEXOPT_DEX2OAT_NEEDED 1
+#define DEXOPT_PATCHOAT_NEEDED 2
+#define DEXOPT_SELF_PATCHOAT_NEEDED 3
+
/* data structures */
typedef struct {
@@ -133,10 +139,8 @@
/* util.c */
-int create_pkg_path_in_dir(char path[PKG_PATH_MAX],
- const dir_rec_t* dir,
- const char* pkgname,
- const char* postfix);
+std::string create_package_data_path(const char* volume_uuid,
+ const char* package_name, userid_t user);
int create_pkg_path(char path[PKG_PATH_MAX],
const char *pkgname,
@@ -203,31 +207,31 @@
/* commands.c */
-int install(const char *pkgname, uid_t uid, gid_t gid, const char *seinfo);
-int uninstall(const char *pkgname, userid_t userid);
+int install(const char *uuid, const char *pkgname, uid_t uid, gid_t gid, const char *seinfo);
+int uninstall(const char *uuid, const char *pkgname, userid_t userid);
int renamepkg(const char *oldpkgname, const char *newpkgname);
-int fix_uid(const char *pkgname, uid_t uid, gid_t gid);
-int delete_user_data(const char *pkgname, userid_t userid);
-int make_user_data(const char *pkgname, uid_t uid, userid_t userid, const char* seinfo);
+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 make_user_data(const char *uuid, const char *pkgname, uid_t uid, userid_t userid, const char* seinfo);
int make_user_config(userid_t userid);
int delete_user(userid_t userid);
-int delete_cache(const char *pkgname, userid_t userid);
-int delete_code_cache(const char *pkgname, userid_t userid);
+int delete_cache(const char *uuid, const char *pkgname, userid_t userid);
+int delete_code_cache(const char *uuid, const char *pkgname, userid_t userid);
int move_dex(const char *src, const char *dst, const char *instruction_set);
int rm_dex(const char *path, const char *instruction_set);
int protect(char *pkgname, gid_t gid);
-int get_size(const char *pkgname, userid_t userid, const char *apkpath, const char *libdirpath,
+int get_size(const char *uuid, const char *pkgname, userid_t userid, const char *apkpath, const char *libdirpath,
const char *fwdlock_apkpath, const char *asecpath, const char *instruction_set,
int64_t *codesize, int64_t *datasize, int64_t *cachesize, int64_t *asecsize);
int free_cache(int64_t free_size);
int dexopt(const char *apk_path, uid_t uid, bool is_public, const char *pkgName,
- const char *instruction_set, bool vm_safe_mode, bool should_relocate, bool debuggable,
- const char* outputPath);
+ const char *instruction_set, int dexopt_needed, bool vm_safe_mode,
+ bool debuggable, const char* oat_dir);
int mark_boot_complete(const char *instruction_set);
int movefiles();
-int linklib(const char* target, const char* source, int userId);
+int linklib(const char *uuid, const char* target, const char* source, int userId);
int idmap(const char *target_path, const char *overlay_path, uid_t uid);
-int restorecon_data(const char* pkgName, const char* seinfo, uid_t uid);
+int restorecon_data(const char *uuid, const char* pkgName, const char* seinfo, uid_t uid);
int create_oat_dir(const char* oat_dir, const char *instruction_set);
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,
diff --git a/cmds/installd/tests/Android.mk b/cmds/installd/tests/Android.mk
index 7300b29..c16375a 100644
--- a/cmds/installd/tests/Android.mk
+++ b/cmds/installd/tests/Android.mk
@@ -8,6 +8,7 @@
installd_utils_test.cpp
shared_libraries := \
+ libbase \
libutils \
libcutils \
diff --git a/cmds/installd/tests/installd_utils_test.cpp b/cmds/installd/tests/installd_utils_test.cpp
index 68d150b..ebf7053 100644
--- a/cmds/installd/tests/installd_utils_test.cpp
+++ b/cmds/installd/tests/installd_utils_test.cpp
@@ -321,6 +321,7 @@
const char *prefix = TEST_DATA_DIR PRIMARY_USER_PREFIX;
size_t offset = strlen(prefix);
+
EXPECT_STREQ(pkgname, path + offset)
<< "Package path should be a really long string of a's";
}
@@ -371,20 +372,6 @@
<< "Package path should be in /data/user/";
}
-TEST_F(UtilsTest, CreatePkgPathInDir_ProtectedDir) {
- char path[PKG_PATH_MAX];
-
- dir_rec_t dir;
- dir.path = (char*) "/data/app-private/";
- dir.len = strlen(dir.path);
-
- EXPECT_EQ(0, create_pkg_path_in_dir(path, &dir, "com.example.package", ".apk"))
- << "Should successfully create package path.";
-
- EXPECT_STREQ("/data/app-private/com.example.package.apk", path)
- << "Package path should be in /data/app-private/";
-}
-
TEST_F(UtilsTest, CreatePersonaPath_Primary) {
char path[PKG_PATH_MAX];
@@ -482,4 +469,14 @@
<< "String should fail because it's too large to fit";
}
+TEST_F(UtilsTest, CreatePackageDataPath) {
+ EXPECT_EQ("/data/data/com.example", create_package_data_path(nullptr, "com.example", 0));
+ EXPECT_EQ("/data/user/10/com.example", create_package_data_path(nullptr, "com.example", 10));
+
+ EXPECT_EQ("/mnt/expand/57f8f4bc-abf4-655f-bf67-946fc0f9f25b/user/0/com.example",
+ create_package_data_path("57f8f4bc-abf4-655f-bf67-946fc0f9f25b", "com.example", 0));
+ EXPECT_EQ("/mnt/expand/57f8f4bc-abf4-655f-bf67-946fc0f9f25b/user/10/com.example",
+ create_package_data_path("57f8f4bc-abf4-655f-bf67-946fc0f9f25b", "com.example", 10));
+}
+
}
diff --git a/cmds/installd/utils.cpp b/cmds/installd/utils.cpp
index df2bbce..763cb42 100644
--- a/cmds/installd/utils.cpp
+++ b/cmds/installd/utils.cpp
@@ -16,86 +16,69 @@
#include "installd.h"
+#include <base/stringprintf.h>
+#include <base/logging.h>
+
#define CACHE_NOISY(x) //x
-int create_pkg_path_in_dir(char path[PKG_PATH_MAX],
- const dir_rec_t* dir,
- const char* pkgname,
- const char* postfix)
-{
- const size_t postfix_len = strlen(postfix);
+using android::base::StringPrintf;
- const size_t pkgname_len = strlen(pkgname);
- if (pkgname_len > PKG_NAME_MAX) {
- return -1;
- }
-
- if (is_valid_package_name(pkgname) < 0) {
- return -1;
- }
-
- if ((pkgname_len + dir->len + postfix_len) >= PKG_PATH_MAX) {
- return -1;
- }
-
- char *dst = path;
- size_t dst_size = PKG_PATH_MAX;
-
- if (append_and_increment(&dst, dir->path, &dst_size) < 0
- || append_and_increment(&dst, pkgname, &dst_size) < 0
- || append_and_increment(&dst, postfix, &dst_size) < 0) {
- ALOGE("Error building APK path");
- return -1;
- }
-
- return 0;
+/**
+ * Check that given string is valid filename, and that it attempts no
+ * parent or child directory traversal.
+ */
+static bool is_valid_filename(const std::string& name) {
+ if (name.empty() || (name == ".") || (name == "..")
+ || (name.find('/') != std::string::npos)) {
+ return false;
+ } else {
+ return true;
+ }
}
/**
- * Create the package path name for a given package name with a postfix for
- * a certain userid. Returns 0 on success, and -1 on failure.
+ * Create the path name where package data should be stored for the given
+ * volume UUID, package name, and user ID. An empty UUID is assumed to be
+ * internal storage.
*/
-int create_pkg_path(char path[PKG_PATH_MAX],
- const char *pkgname,
- const char *postfix,
- userid_t userid)
-{
- size_t userid_len;
- const char* userid_prefix;
- if (userid == 0) {
- userid_prefix = PRIMARY_USER_PREFIX;
- userid_len = 0;
+std::string create_package_data_path(const char* volume_uuid,
+ const char* package_name, userid_t user) {
+ CHECK(is_valid_filename(package_name));
+ CHECK(is_valid_package_name(package_name) == 0);
+
+ if (volume_uuid == nullptr) {
+ if (user == 0) {
+ // /data/data/com.example
+ return StringPrintf("%sdata/%s", android_data_dir.path, package_name);
+ } else {
+ // /data/user/0/com.example
+ return StringPrintf("%suser/%u/%s", android_data_dir.path, user, package_name);
+ }
} else {
- userid_prefix = SECONDARY_USER_PREFIX;
- userid_len = snprintf(NULL, 0, "%d", userid);
+ CHECK(is_valid_filename(volume_uuid));
+
+ // /mnt/expand/uuid/user/0/com.example
+ return StringPrintf("%s%s/user/%u/%s", android_mnt_expand_dir.path,
+ volume_uuid, user, package_name);
}
+}
- const size_t prefix_len = android_data_dir.len + strlen(userid_prefix)
- + userid_len + 1 /*slash*/;
- char prefix[prefix_len + 1];
-
- char *dst = prefix;
- size_t dst_size = sizeof(prefix);
-
- if (append_and_increment(&dst, android_data_dir.path, &dst_size) < 0
- || append_and_increment(&dst, userid_prefix, &dst_size) < 0) {
- ALOGE("Error building prefix for APK path");
+int create_pkg_path(char path[PKG_PATH_MAX], const char *pkgname,
+ const char *postfix, userid_t userid) {
+ if (is_valid_package_name(pkgname) != 0) {
+ path[0] = '\0';
return -1;
}
- if (userid != 0) {
- int ret = snprintf(dst, dst_size, "%d/", userid);
- if (ret < 0 || (size_t) ret != userid_len + 1) {
- ALOGW("Error appending UID to APK path");
- return -1;
- }
+ std::string _tmp(create_package_data_path(nullptr, pkgname, userid) + postfix);
+ const char* tmp = _tmp.c_str();
+ if (strlen(tmp) >= PKG_PATH_MAX) {
+ path[0] = '\0';
+ return -1;
+ } else {
+ strcpy(path, tmp);
+ return 0;
}
-
- dir_rec_t dir;
- dir.path = prefix;
- dir.len = prefix_len;
-
- return create_pkg_path_in_dir(path, &dir, pkgname, postfix);
}
/**
@@ -182,6 +165,10 @@
const char *x = pkgname;
int alpha = -1;
+ if (strlen(pkgname) > PKG_NAME_MAX) {
+ return -1;
+ }
+
while (*x) {
if (isalnum(*x) || (*x == '_')) {
/* alphanumeric or underscore are fine */