Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d845c961 authored by Narayan Kamath's avatar Narayan Kamath
Browse files

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
parent 13b16040
Loading
Loading
Loading
Loading
+25 −0
Original line number Original line Diff line number Diff line
@@ -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 */);
    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,
int calculate_oat_file_path(char path[PKG_PATH_MAX], const char *oat_dir, const char *apk_path,
        const char *instruction_set) {
        const char *instruction_set) {
    char *file_name_start;
    char *file_name_start;
+8 −1
Original line number Original line Diff line number Diff line
@@ -179,6 +179,12 @@ static int do_rm_package_dir(char **arg, char reply[REPLY_MAX] __unused)
    return rm_package_dir(arg[0]);
    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 {
struct cmdinfo {
    const char *name;
    const char *name;
    unsigned numargs;
    unsigned numargs;
@@ -210,6 +216,7 @@ struct cmdinfo cmds[] = {
    { "restorecondata",       4, do_restorecon_data },
    { "restorecondata",       4, do_restorecon_data },
    { "createoatdir",         2, do_create_oat_dir },
    { "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)
static int readx(int s, void *_buf, int count)
+2 −0
Original line number Original line Diff line number Diff line
@@ -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 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(const char *path);
int validate_apk_path_subdirs(const char *path);


int append_and_increment(char** dst, const char* src, size_t* dst_size);
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);
                            const char *instruction_set);
int move_package_dir(char path[PKG_PATH_MAX], const char *oat_dir, const char *apk_path,
int move_package_dir(char path[PKG_PATH_MAX], const char *oat_dir, const char *apk_path,
                            const char *instruction_set);
                            const char *instruction_set);
int link_file(const char *relative_path, const char *from_base, const char *to_base);
+16 −8
Original line number Original line Diff line number Diff line
@@ -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
 * Check whether path points to a valid path for an APK file. The path must
 * subdirectory names is allowed. Returns -1 when an invalid path is encountered
 * begin with a whitelisted prefix path and must be no deeper than |maxSubdirs| within
 * and 0 when a valid path is encountered.
 * 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;
    const dir_rec_t* dir = NULL;
    int maxSubdirs = 1;

    if (!strncmp(path, android_app_dir.path, android_app_dir.len)) {
    if (!strncmp(path, android_app_dir.path, android_app_dir.len)) {
        dir = &android_app_dir;
        dir = &android_app_dir;
    } else if (!strncmp(path, android_app_private_dir.path, android_app_private_dir.len)) {
    } 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;
        dir = &android_asec_dir;
    } else if (!strncmp(path, android_mnt_expand_dir.path, android_mnt_expand_dir.len)) {
    } else if (!strncmp(path, android_mnt_expand_dir.path, android_mnt_expand_dir.len)) {
        dir = &android_mnt_expand_dir;
        dir = &android_mnt_expand_dir;
        if (maxSubdirs < 2) {
            maxSubdirs = 2;
            maxSubdirs = 2;
        }
    } else {
    } else {
        return -1;
        return -1;
    }
    }
@@ -1068,6 +1068,14 @@ int validate_apk_path(const char *path)
    return validate_path(dir, path, maxSubdirs);
    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) {
int append_and_increment(char** dst, const char* src, size_t* dst_size) {
    ssize_t ret = strlcpy(*dst, src, *dst_size);
    ssize_t ret = strlcpy(*dst, src, *dst_size);
    if (ret < 0 || (size_t) ret >= *dst_size) {
    if (ret < 0 || (size_t) ret >= *dst_size) {