summaryrefslogtreecommitdiffstats
path: root/cmds
diff options
context:
space:
mode:
authorNarayan Kamath <narayan@google.com>2015-06-04 13:20:27 +0100
committerNarayan Kamath <narayan@google.com>2015-06-09 11:35:43 +0100
commitd845c96128a40ca5802c0840ae190fa0af7d4735 (patch)
tree22602a1157dcd942fec284411648b60c0a5827eb /cmds
parent13b1604018968408bcc5553e1fa5ea9df3e4e009 (diff)
downloadframeworks_native-d845c96128a40ca5802c0840ae190fa0af7d4735.zip
frameworks_native-d845c96128a40ca5802c0840ae190fa0af7d4735.tar.gz
frameworks_native-d845c96128a40ca5802c0840ae190fa0af7d4735.tar.bz2
Add an installd command to link files
Given a pair of absolute paths {from_path, to_path} , check that they are both valid apk subpaths (eg. /data/app/package/foo) and link(2) to_path to from_path. This is required by staged installs, where we link existing apks and oat files to their staging location. bug: 20889739 Change-Id: I3b5e3b43677af68be59308121a4409caaa6a72f0
Diffstat (limited to 'cmds')
-rw-r--r--cmds/installd/commands.cpp25
-rw-r--r--cmds/installd/installd.cpp9
-rw-r--r--cmds/installd/installd.h2
-rw-r--r--cmds/installd/utils.cpp24
4 files changed, 51 insertions, 9 deletions
diff --git a/cmds/installd/commands.cpp b/cmds/installd/commands.cpp
index 99da968..ebd71a0 100644
--- a/cmds/installd/commands.cpp
+++ b/cmds/installd/commands.cpp
@@ -1778,6 +1778,31 @@ int rm_package_dir(const char* apk_path)
return delete_dir_contents(apk_path, 1 /* also_delete_dir */ , NULL /* exclusion_predicate */);
}
+int link_file(const char* relative_path, const char* from_base, const char* to_base) {
+ char from_path[PKG_PATH_MAX];
+ char to_path[PKG_PATH_MAX];
+ snprintf(from_path, PKG_PATH_MAX, "%s/%s", from_base, relative_path);
+ snprintf(to_path, PKG_PATH_MAX, "%s/%s", to_base, relative_path);
+
+ if (validate_apk_path_subdirs(from_path)) {
+ ALOGE("invalid app data sub-path '%s' (bad prefix)\n", from_path);
+ return -1;
+ }
+
+ if (validate_apk_path_subdirs(to_path)) {
+ ALOGE("invalid app data sub-path '%s' (bad prefix)\n", to_path);
+ return -1;
+ }
+
+ const int ret = link(from_path, to_path);
+ if (ret < 0) {
+ ALOGE("link(%s, %s) failed : %s", from_path, to_path, strerror(errno));
+ return -1;
+ }
+
+ return 0;
+}
+
int calculate_oat_file_path(char path[PKG_PATH_MAX], const char *oat_dir, const char *apk_path,
const char *instruction_set) {
char *file_name_start;
diff --git a/cmds/installd/installd.cpp b/cmds/installd/installd.cpp
index 01e7cdd..297b3a1 100644
--- a/cmds/installd/installd.cpp
+++ b/cmds/installd/installd.cpp
@@ -179,6 +179,12 @@ static int do_rm_package_dir(char **arg, char reply[REPLY_MAX] __unused)
return rm_package_dir(arg[0]);
}
+static int do_link_file(char **arg, char reply[REPLY_MAX] __unused)
+{
+ /* relative_path, from_base, to_base */
+ return link_file(arg[0], arg[1], arg[2]);
+}
+
struct cmdinfo {
const char *name;
unsigned numargs;
@@ -209,7 +215,8 @@ struct cmdinfo cmds[] = {
{ "idmap", 3, do_idmap },
{ "restorecondata", 4, do_restorecon_data },
{ "createoatdir", 2, do_create_oat_dir },
- { "rmpackagedir", 1, do_rm_package_dir},
+ { "rmpackagedir", 1, do_rm_package_dir },
+ { "linkfile", 3, do_link_file }
};
static int readx(int s, void *_buf, int count)
diff --git a/cmds/installd/installd.h b/cmds/installd/installd.h
index ce6c857..744ed3a 100644
--- a/cmds/installd/installd.h
+++ b/cmds/installd/installd.h
@@ -203,6 +203,7 @@ 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 validate_apk_path_subdirs(const char *path);
int append_and_increment(char** dst, const char* src, size_t* dst_size);
@@ -254,3 +255,4 @@ int calculate_oat_file_path(char path[PKG_PATH_MAX], const char *oat_dir, const
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);
+int link_file(const char *relative_path, const char *from_base, const char *to_base);
diff --git a/cmds/installd/utils.cpp b/cmds/installd/utils.cpp
index 3f679a2..7db3fb9 100644
--- a/cmds/installd/utils.cpp
+++ b/cmds/installd/utils.cpp
@@ -1043,15 +1043,13 @@ int copy_and_append(dir_rec_t* dst, const dir_rec_t* src, const char* suffix) {
}
/**
- * Check whether path points to a valid path for an APK file. Only one level of
- * subdirectory names is allowed. Returns -1 when an invalid path is encountered
- * and 0 when a valid path is encountered.
+ * Check whether path points to a valid path for an APK file. The path must
+ * begin with a whitelisted prefix path and must be no deeper than |maxSubdirs| within
+ * that path. Returns -1 when an invalid path is encountered and 0 when a valid path
+ * is encountered.
*/
-int validate_apk_path(const char *path)
-{
+static int validate_apk_path_internal(const char *path, int maxSubdirs) {
const dir_rec_t* dir = NULL;
- int maxSubdirs = 1;
-
if (!strncmp(path, android_app_dir.path, android_app_dir.len)) {
dir = &android_app_dir;
} else if (!strncmp(path, android_app_private_dir.path, android_app_private_dir.len)) {
@@ -1060,7 +1058,9 @@ int validate_apk_path(const char *path)
dir = &android_asec_dir;
} else if (!strncmp(path, android_mnt_expand_dir.path, android_mnt_expand_dir.len)) {
dir = &android_mnt_expand_dir;
- maxSubdirs = 2;
+ if (maxSubdirs < 2) {
+ maxSubdirs = 2;
+ }
} else {
return -1;
}
@@ -1068,6 +1068,14 @@ int validate_apk_path(const char *path)
return validate_path(dir, path, maxSubdirs);
}
+int validate_apk_path(const char* path) {
+ return validate_apk_path_internal(path, 1 /* maxSubdirs */);
+}
+
+int validate_apk_path_subdirs(const char* path) {
+ return validate_apk_path_internal(path, 3 /* maxSubdirs */);
+}
+
int append_and_increment(char** dst, const char* src, size_t* dst_size) {
ssize_t ret = strlcpy(*dst, src, *dst_size);
if (ret < 0 || (size_t) ret >= *dst_size) {