Merge "Plumb through volume UUID when building paths."
This commit is contained in:
commit
d107c305f7
@ -12,6 +12,7 @@ LOCAL_MODULE := libinstalld
|
|||||||
LOCAL_MODULE_TAGS := eng tests
|
LOCAL_MODULE_TAGS := eng tests
|
||||||
LOCAL_SRC_FILES := $(common_src_files)
|
LOCAL_SRC_FILES := $(common_src_files)
|
||||||
LOCAL_CFLAGS := $(common_cflags)
|
LOCAL_CFLAGS := $(common_cflags)
|
||||||
|
LOCAL_SHARED_LIBRARIES := libbase
|
||||||
LOCAL_ADDITIONAL_DEPENDENCIES += $(LOCAL_PATH)/Android.mk
|
LOCAL_ADDITIONAL_DEPENDENCIES += $(LOCAL_PATH)/Android.mk
|
||||||
include $(BUILD_STATIC_LIBRARY)
|
include $(BUILD_STATIC_LIBRARY)
|
||||||
|
|
||||||
@ -24,7 +25,12 @@ LOCAL_MODULE := installd
|
|||||||
LOCAL_MODULE_TAGS := optional
|
LOCAL_MODULE_TAGS := optional
|
||||||
LOCAL_CFLAGS := $(common_cflags)
|
LOCAL_CFLAGS := $(common_cflags)
|
||||||
LOCAL_SRC_FILES := installd.cpp $(common_src_files)
|
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_STATIC_LIBRARIES := libdiskusage
|
||||||
LOCAL_ADDITIONAL_DEPENDENCIES += $(LOCAL_PATH)/Android.mk
|
LOCAL_ADDITIONAL_DEPENDENCIES += $(LOCAL_PATH)/Android.mk
|
||||||
include $(BUILD_EXECUTABLE)
|
include $(BUILD_EXECUTABLE)
|
||||||
|
@ -33,11 +33,8 @@ dir_rec_t android_media_dir;
|
|||||||
dir_rec_t android_mnt_expand_dir;
|
dir_rec_t android_mnt_expand_dir;
|
||||||
dir_rec_array_t android_system_dirs;
|
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;
|
struct stat libStat;
|
||||||
|
|
||||||
if ((uid < AID_SYSTEM) || (gid < AID_SYSTEM)) {
|
if ((uid < AID_SYSTEM) || (gid < AID_SYSTEM)) {
|
||||||
@ -45,20 +42,8 @@ int install(const char *pkgname, uid_t uid, gid_t gid, const char *seinfo)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (create_pkg_path(pkgdir, pkgname, PKG_DIR_POSTFIX, 0)) {
|
std::string _pkgdir(create_package_data_path(uuid, pkgname, 0));
|
||||||
ALOGE("cannot create package path\n");
|
const char* pkgdir = _pkgdir.c_str();
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mkdir(pkgdir, 0751) < 0) {
|
if (mkdir(pkgdir, 0751) < 0) {
|
||||||
ALOGE("cannot create dir '%s': %s\n", pkgdir, strerror(errno));
|
ALOGE("cannot create dir '%s': %s\n", pkgdir, strerror(errno));
|
||||||
@ -70,42 +55,14 @@ int install(const char *pkgname, uid_t uid, gid_t gid, const char *seinfo)
|
|||||||
return -1;
|
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) {
|
if (selinux_android_setfilecon(pkgdir, pkgname, seinfo, uid) < 0) {
|
||||||
ALOGE("cannot setfilecon dir '%s': %s\n", pkgdir, strerror(errno));
|
ALOGE("cannot setfilecon dir '%s': %s\n", pkgdir, strerror(errno));
|
||||||
unlink(libsymlink);
|
|
||||||
unlink(pkgdir);
|
unlink(pkgdir);
|
||||||
return -errno;
|
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) {
|
if (chown(pkgdir, uid, gid) < 0) {
|
||||||
ALOGE("cannot chown dir '%s': %s\n", pkgdir, strerror(errno));
|
ALOGE("cannot chown dir '%s': %s\n", pkgdir, strerror(errno));
|
||||||
unlink(libsymlink);
|
|
||||||
unlink(pkgdir);
|
unlink(pkgdir);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -113,12 +70,10 @@ int install(const char *pkgname, uid_t uid, gid_t gid, const char *seinfo)
|
|||||||
return 0;
|
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];
|
std::string _pkgdir(create_package_data_path(uuid, pkgname, userid));
|
||||||
|
const char* pkgdir = _pkgdir.c_str();
|
||||||
if (create_pkg_path(pkgdir, pkgname, PKG_DIR_POSTFIX, userid))
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
remove_profile_file(pkgname);
|
remove_profile_file(pkgname);
|
||||||
|
|
||||||
@ -143,9 +98,8 @@ int renamepkg(const char *oldpkgname, const char *newpkgname)
|
|||||||
return 0;
|
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;
|
struct stat s;
|
||||||
|
|
||||||
if ((uid < AID_SYSTEM) || (gid < AID_SYSTEM)) {
|
if ((uid < AID_SYSTEM) || (gid < AID_SYSTEM)) {
|
||||||
@ -153,10 +107,8 @@ int fix_uid(const char *pkgname, uid_t uid, gid_t gid)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (create_pkg_path(pkgdir, pkgname, PKG_DIR_POSTFIX, 0)) {
|
std::string _pkgdir(create_package_data_path(uuid, pkgname, 0));
|
||||||
ALOGE("cannot create package path\n");
|
const char* pkgdir = _pkgdir.c_str();
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (stat(pkgdir, &s) < 0) return -1;
|
if (stat(pkgdir, &s) < 0) return -1;
|
||||||
|
|
||||||
@ -179,35 +131,20 @@ int fix_uid(const char *pkgname, uid_t uid, gid_t gid)
|
|||||||
return 0;
|
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];
|
std::string _pkgdir(create_package_data_path(uuid, pkgname, userid));
|
||||||
|
const char* pkgdir = _pkgdir.c_str();
|
||||||
if (create_pkg_path(pkgdir, pkgname, PKG_DIR_POSTFIX, userid))
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
return delete_dir_contents(pkgdir, 0, NULL);
|
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;
|
struct stat libStat;
|
||||||
|
|
||||||
// Create the data dir for the package
|
std::string _pkgdir(create_package_data_path(uuid, pkgname, userid));
|
||||||
if (create_pkg_path(pkgdir, pkgname, PKG_DIR_POSTFIX, userid)) {
|
const char* pkgdir = _pkgdir.c_str();
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mkdir(pkgdir, 0751) < 0) {
|
if (mkdir(pkgdir, 0751) < 0) {
|
||||||
ALOGE("cannot create dir '%s': %s\n", pkgdir, strerror(errno));
|
ALOGE("cannot create dir '%s': %s\n", pkgdir, strerror(errno));
|
||||||
@ -219,47 +156,14 @@ int make_user_data(const char *pkgname, uid_t uid, userid_t userid, const char*
|
|||||||
return -errno;
|
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) {
|
if (selinux_android_setfilecon(pkgdir, pkgname, seinfo, uid) < 0) {
|
||||||
ALOGE("cannot setfilecon dir '%s': %s\n", pkgdir, strerror(errno));
|
ALOGE("cannot setfilecon dir '%s': %s\n", pkgdir, strerror(errno));
|
||||||
unlink(libsymlink);
|
|
||||||
unlink(pkgdir);
|
unlink(pkgdir);
|
||||||
return -errno;
|
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) {
|
if (chown(pkgdir, uid, uid) < 0) {
|
||||||
ALOGE("cannot chown dir '%s': %s\n", pkgdir, strerror(errno));
|
ALOGE("cannot chown dir '%s': %s\n", pkgdir, strerror(errno));
|
||||||
unlink(libsymlink);
|
|
||||||
unlink(pkgdir);
|
unlink(pkgdir);
|
||||||
return -errno;
|
return -errno;
|
||||||
}
|
}
|
||||||
@ -301,24 +205,23 @@ int delete_user(userid_t userid)
|
|||||||
return status;
|
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];
|
std::string _cachedir(
|
||||||
|
create_package_data_path(uuid, pkgname, userid) + CACHE_DIR_POSTFIX);
|
||||||
if (create_pkg_path(cachedir, pkgname, CACHE_DIR_POSTFIX, userid))
|
const char* cachedir = _cachedir.c_str();
|
||||||
return -1;
|
|
||||||
|
|
||||||
/* delete contents, not the directory, no exceptions */
|
/* delete contents, not the directory, no exceptions */
|
||||||
return delete_dir_contents(cachedir, 0, NULL);
|
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];
|
std::string _codecachedir(
|
||||||
struct stat s;
|
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))
|
struct stat s;
|
||||||
return -1;
|
|
||||||
|
|
||||||
/* it's okay if code cache is missing */
|
/* it's okay if code cache is missing */
|
||||||
if (lstat(codecachedir, &s) == -1 && errno == ENOENT) {
|
if (lstat(codecachedir, &s) == -1 && errno == ENOENT) {
|
||||||
@ -336,6 +239,7 @@ int delete_code_cache(const char *pkgname, userid_t userid)
|
|||||||
* also require that apps constantly modify file metadata even
|
* also require that apps constantly modify file metadata even
|
||||||
* when just reading from the cache, which is pretty awful.
|
* when just reading from the cache, which is pretty awful.
|
||||||
*/
|
*/
|
||||||
|
// TODO: extend to know about other volumes
|
||||||
int free_cache(int64_t free_size)
|
int free_cache(int64_t free_size)
|
||||||
{
|
{
|
||||||
cache_t* cache;
|
cache_t* cache;
|
||||||
@ -467,7 +371,7 @@ int rm_dex(const char *path, const char *instruction_set)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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 *libdirpath, const char *fwdlock_apkpath, const char *asecpath,
|
||||||
const char *instruction_set, int64_t *_codesize, int64_t *_datasize,
|
const char *instruction_set, int64_t *_codesize, int64_t *_datasize,
|
||||||
int64_t *_cachesize, int64_t* _asecsize)
|
int64_t *_cachesize, int64_t* _asecsize)
|
||||||
@ -524,11 +428,10 @@ int get_size(const char *pkgname, userid_t userid, const char *apkpath,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (create_pkg_path(path, pkgname, PKG_DIR_POSTFIX, userid)) {
|
std::string _pkgdir(create_package_data_path(uuid, pkgname, userid));
|
||||||
goto done;
|
const char* pkgdir = _pkgdir.c_str();
|
||||||
}
|
|
||||||
|
|
||||||
d = opendir(path);
|
d = opendir(pkgdir);
|
||||||
if (d == NULL) {
|
if (d == NULL) {
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
@ -1457,21 +1360,16 @@ done:
|
|||||||
return 0;
|
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;
|
struct stat s, libStat;
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
|
|
||||||
if (create_pkg_path(pkgdir, pkgname, PKG_DIR_POSTFIX, userId)) {
|
std::string _pkgdir(create_package_data_path(uuid, pkgname, userId));
|
||||||
ALOGE("cannot create package path\n");
|
std::string _libsymlink(_pkgdir + PKG_LIB_POSTFIX);
|
||||||
return -1;
|
|
||||||
}
|
const char* pkgdir = _pkgdir.c_str();
|
||||||
if (create_pkg_path(libsymlink, pkgname, PKG_LIB_POSTFIX, userId)) {
|
const char* libsymlink = _libsymlink.c_str();
|
||||||
ALOGE("cannot create package lib symlink origin path\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (stat(pkgdir, &s) < 0) return -1;
|
if (stat(pkgdir, &s) < 0) return -1;
|
||||||
|
|
||||||
@ -1640,7 +1538,8 @@ fail:
|
|||||||
return -1;
|
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;
|
struct dirent *entry;
|
||||||
DIR *d;
|
DIR *d;
|
||||||
|
@ -33,7 +33,7 @@ static int do_ping(char **arg __unused, char reply[REPLY_MAX] __unused)
|
|||||||
|
|
||||||
static int do_install(char **arg, char reply[REPLY_MAX] __unused)
|
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)
|
static int do_dexopt(char **arg, char reply[REPLY_MAX] __unused)
|
||||||
@ -61,7 +61,7 @@ static int do_rm_dex(char **arg, char reply[REPLY_MAX] __unused)
|
|||||||
|
|
||||||
static int do_remove(char **arg, char reply[REPLY_MAX] __unused)
|
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)
|
static int do_rename(char **arg, char reply[REPLY_MAX] __unused)
|
||||||
@ -71,7 +71,7 @@ static int do_rename(char **arg, char reply[REPLY_MAX] __unused)
|
|||||||
|
|
||||||
static int do_fixuid(char **arg, char reply[REPLY_MAX] __unused)
|
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 */
|
static int do_free_cache(char **arg, char reply[REPLY_MAX] __unused) /* TODO int:free_size */
|
||||||
@ -81,12 +81,12 @@ static int do_free_cache(char **arg, char reply[REPLY_MAX] __unused) /* TODO int
|
|||||||
|
|
||||||
static int do_rm_cache(char **arg, char reply[REPLY_MAX] __unused)
|
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)
|
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])
|
static int do_get_size(char **arg, char reply[REPLY_MAX])
|
||||||
@ -98,7 +98,7 @@ static int do_get_size(char **arg, char reply[REPLY_MAX])
|
|||||||
int res = 0;
|
int res = 0;
|
||||||
|
|
||||||
/* pkgdir, userid, apkpath */
|
/* 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);
|
arg[6], &codesize, &datasize, &cachesize, &asecsize);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -112,12 +112,12 @@ static int do_get_size(char **arg, char reply[REPLY_MAX])
|
|||||||
|
|
||||||
static int do_rm_user_data(char **arg, char reply[REPLY_MAX] __unused)
|
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)
|
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 */
|
/* pkgname, uid, userid, seinfo */
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -138,7 +138,7 @@ static int do_movefiles(char **arg __unused, char reply[REPLY_MAX] __unused)
|
|||||||
|
|
||||||
static int do_linklib(char **arg, char reply[REPLY_MAX] __unused)
|
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)
|
static int do_idmap(char **arg, char reply[REPLY_MAX] __unused)
|
||||||
@ -148,7 +148,7 @@ static int do_idmap(char **arg, char reply[REPLY_MAX] __unused)
|
|||||||
|
|
||||||
static int do_restorecon_data(char **arg, char reply[REPLY_MAX] __attribute__((unused)))
|
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*/
|
/* pkgName, seinfo, uid*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,6 +31,7 @@
|
|||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
#include <cutils/fs.h>
|
#include <cutils/fs.h>
|
||||||
#include <cutils/sockets.h>
|
#include <cutils/sockets.h>
|
||||||
@ -138,10 +139,8 @@ typedef struct {
|
|||||||
|
|
||||||
/* util.c */
|
/* util.c */
|
||||||
|
|
||||||
int create_pkg_path_in_dir(char path[PKG_PATH_MAX],
|
std::string create_package_data_path(const char* volume_uuid,
|
||||||
const dir_rec_t* dir,
|
const char* package_name, userid_t user);
|
||||||
const char* pkgname,
|
|
||||||
const char* postfix);
|
|
||||||
|
|
||||||
int create_pkg_path(char path[PKG_PATH_MAX],
|
int create_pkg_path(char path[PKG_PATH_MAX],
|
||||||
const char *pkgname,
|
const char *pkgname,
|
||||||
@ -208,20 +207,20 @@ void remove_profile_file(const char *pkgname);
|
|||||||
|
|
||||||
/* commands.c */
|
/* commands.c */
|
||||||
|
|
||||||
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);
|
||||||
int uninstall(const char *pkgname, userid_t userid);
|
int uninstall(const char *uuid, const char *pkgname, userid_t userid);
|
||||||
int renamepkg(const char *oldpkgname, const char *newpkgname);
|
int renamepkg(const char *oldpkgname, const char *newpkgname);
|
||||||
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);
|
||||||
int delete_user_data(const char *pkgname, userid_t userid);
|
int delete_user_data(const char *uuid, const char *pkgname, userid_t userid);
|
||||||
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);
|
||||||
int make_user_config(userid_t userid);
|
int make_user_config(userid_t userid);
|
||||||
int delete_user(userid_t userid);
|
int delete_user(userid_t userid);
|
||||||
int delete_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 *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 move_dex(const char *src, const char *dst, const char *instruction_set);
|
||||||
int rm_dex(const char *path, const char *instruction_set);
|
int rm_dex(const char *path, const char *instruction_set);
|
||||||
int protect(char *pkgname, gid_t gid);
|
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,
|
const char *fwdlock_apkpath, const char *asecpath, const char *instruction_set,
|
||||||
int64_t *codesize, int64_t *datasize, int64_t *cachesize, int64_t *asecsize);
|
int64_t *codesize, int64_t *datasize, int64_t *cachesize, int64_t *asecsize);
|
||||||
int free_cache(int64_t free_size);
|
int free_cache(int64_t free_size);
|
||||||
@ -230,9 +229,9 @@ int dexopt(const char *apk_path, uid_t uid, bool is_public, const char *pkgName,
|
|||||||
bool debuggable, const char* oat_dir);
|
bool debuggable, const char* oat_dir);
|
||||||
int mark_boot_complete(const char *instruction_set);
|
int mark_boot_complete(const char *instruction_set);
|
||||||
int movefiles();
|
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 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 create_oat_dir(const char* oat_dir, const char *instruction_set);
|
||||||
int rm_package_dir(const char* apk_path);
|
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,
|
int calculate_oat_file_path(char path[PKG_PATH_MAX], const char *oat_dir, const char *apk_path,
|
||||||
|
@ -8,6 +8,7 @@ test_src_files := \
|
|||||||
installd_utils_test.cpp
|
installd_utils_test.cpp
|
||||||
|
|
||||||
shared_libraries := \
|
shared_libraries := \
|
||||||
|
libbase \
|
||||||
libutils \
|
libutils \
|
||||||
libcutils \
|
libcutils \
|
||||||
|
|
||||||
|
@ -321,6 +321,7 @@ TEST_F(UtilsTest, CreatePkgPath_LongPkgNameSuccess) {
|
|||||||
|
|
||||||
const char *prefix = TEST_DATA_DIR PRIMARY_USER_PREFIX;
|
const char *prefix = TEST_DATA_DIR PRIMARY_USER_PREFIX;
|
||||||
size_t offset = strlen(prefix);
|
size_t offset = strlen(prefix);
|
||||||
|
|
||||||
EXPECT_STREQ(pkgname, path + offset)
|
EXPECT_STREQ(pkgname, path + offset)
|
||||||
<< "Package path should be a really long string of a's";
|
<< "Package path should be a really long string of a's";
|
||||||
}
|
}
|
||||||
@ -371,20 +372,6 @@ TEST_F(UtilsTest, CreatePkgPath_SecondaryUser) {
|
|||||||
<< "Package path should be in /data/user/";
|
<< "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) {
|
TEST_F(UtilsTest, CreatePersonaPath_Primary) {
|
||||||
char path[PKG_PATH_MAX];
|
char path[PKG_PATH_MAX];
|
||||||
|
|
||||||
@ -482,4 +469,14 @@ TEST_F(UtilsTest, AppendAndIncrement_TooBig) {
|
|||||||
<< "String should fail because it's too large to fit";
|
<< "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));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -16,88 +16,71 @@
|
|||||||
|
|
||||||
#include "installd.h"
|
#include "installd.h"
|
||||||
|
|
||||||
|
#include <base/stringprintf.h>
|
||||||
|
#include <base/logging.h>
|
||||||
|
|
||||||
#define CACHE_NOISY(x) //x
|
#define CACHE_NOISY(x) //x
|
||||||
|
|
||||||
int create_pkg_path_in_dir(char path[PKG_PATH_MAX],
|
using android::base::StringPrintf;
|
||||||
const dir_rec_t* dir,
|
|
||||||
const char* pkgname,
|
|
||||||
const char* postfix)
|
|
||||||
{
|
|
||||||
const size_t postfix_len = strlen(postfix);
|
|
||||||
|
|
||||||
const size_t pkgname_len = strlen(pkgname);
|
/**
|
||||||
if (pkgname_len > PKG_NAME_MAX) {
|
* Check that given string is valid filename, and that it attempts no
|
||||||
return -1;
|
* 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create the package path name for a given package name with a postfix for
|
* Create the path name where package data should be stored for the given
|
||||||
* a certain userid. Returns 0 on success, and -1 on failure.
|
* 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],
|
std::string create_package_data_path(const char* volume_uuid,
|
||||||
const char *pkgname,
|
const char* package_name, userid_t user) {
|
||||||
const char *postfix,
|
CHECK(is_valid_filename(package_name));
|
||||||
userid_t userid)
|
CHECK(is_valid_package_name(package_name) == 0);
|
||||||
{
|
|
||||||
size_t userid_len;
|
if (volume_uuid == nullptr) {
|
||||||
const char* userid_prefix;
|
if (user == 0) {
|
||||||
if (userid == 0) {
|
// /data/data/com.example
|
||||||
userid_prefix = PRIMARY_USER_PREFIX;
|
return StringPrintf("%sdata/%s", android_data_dir.path, package_name);
|
||||||
userid_len = 0;
|
|
||||||
} else {
|
} else {
|
||||||
userid_prefix = SECONDARY_USER_PREFIX;
|
// /data/user/0/com.example
|
||||||
userid_len = snprintf(NULL, 0, "%d", userid);
|
return StringPrintf("%suser/%u/%s", android_data_dir.path, user, package_name);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
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)
|
int create_pkg_path(char path[PKG_PATH_MAX], const char *pkgname,
|
||||||
+ userid_len + 1 /*slash*/;
|
const char *postfix, userid_t userid) {
|
||||||
char prefix[prefix_len + 1];
|
if (is_valid_package_name(pkgname) != 0) {
|
||||||
|
path[0] = '\0';
|
||||||
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");
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (userid != 0) {
|
std::string _tmp(create_package_data_path(nullptr, pkgname, userid) + postfix);
|
||||||
int ret = snprintf(dst, dst_size, "%d/", userid);
|
const char* tmp = _tmp.c_str();
|
||||||
if (ret < 0 || (size_t) ret != userid_len + 1) {
|
if (strlen(tmp) >= PKG_PATH_MAX) {
|
||||||
ALOGW("Error appending UID to APK path");
|
path[0] = '\0';
|
||||||
return -1;
|
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create the path name for user data for a certain userid.
|
* Create the path name for user data for a certain userid.
|
||||||
* Returns 0 on success, and -1 on failure.
|
* Returns 0 on success, and -1 on failure.
|
||||||
@ -182,6 +165,10 @@ int is_valid_package_name(const char* pkgname) {
|
|||||||
const char *x = pkgname;
|
const char *x = pkgname;
|
||||||
int alpha = -1;
|
int alpha = -1;
|
||||||
|
|
||||||
|
if (strlen(pkgname) > PKG_NAME_MAX) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
while (*x) {
|
while (*x) {
|
||||||
if (isalnum(*x) || (*x == '_')) {
|
if (isalnum(*x) || (*x == '_')) {
|
||||||
/* alphanumeric or underscore are fine */
|
/* alphanumeric or underscore are fine */
|
||||||
|
Loading…
Reference in New Issue
Block a user