static const char* kCpPath = "/system/bin/cp";
-int install(const char *uuid, const char *pkgname, uid_t uid, gid_t gid, const char *seinfo) {
- if ((uid < AID_SYSTEM) || (gid < AID_SYSTEM)) {
- ALOGE("invalid uid/gid: %d %d\n", uid, gid);
- return -1;
- }
-
- return make_user_data(uuid, pkgname, uid, 0, seinfo);
-}
-
-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));
-
- int res = 0;
- res |= delete_dir_contents_and_dir(ce_package_path);
- // TODO: include result once 25796509 is fixed
- 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)
-{
- struct stat s;
-
- if ((uid < AID_SYSTEM) || (gid < AID_SYSTEM)) {
- ALOGE("invalid uid/gid: %d %d\n", uid, gid);
- return -1;
- }
-
- // TODO: handle user_de paths
- std::string _pkgdir(create_data_user_package_path(uuid, 0, pkgname));
- const char* pkgdir = _pkgdir.c_str();
-
- if (stat(pkgdir, &s) < 0) return -1;
-
- if (s.st_uid != 0 || s.st_gid != 0) {
- ALOGE("fixing uid of non-root pkg: %s %" PRIu32 " %" PRIu32 "\n", pkgdir, s.st_uid, s.st_gid);
- return -1;
- }
-
- if (chmod(pkgdir, 0751) < 0) {
- ALOGE("cannot chmod dir '%s': %s\n", pkgdir, strerror(errno));
- unlink(pkgdir);
- return -errno;
+int create_app_data(const char *uuid, const char *pkgname, userid_t userid, int flags,
+ appid_t appid, const char* seinfo) {
+ uid_t uid = multiuser_get_uid(userid, appid);
+ if (flags & FLAG_CE_STORAGE) {
+ auto path = create_data_user_package_path(uuid, userid, pkgname);
+ if (fs_prepare_dir_strict(path.c_str(), 0751, uid, uid) != 0) {
+ PLOG(ERROR) << "Failed to prepare " << path;
+ return -1;
+ }
+ if (selinux_android_setfilecon(path.c_str(), pkgname, seinfo, uid) < 0) {
+ PLOG(ERROR) << "Failed to setfilecon " << path;
+ return -1;
+ }
}
- if (chown(pkgdir, uid, gid) < 0) {
- ALOGE("cannot chown dir '%s': %s\n", pkgdir, strerror(errno));
- unlink(pkgdir);
- return -errno;
+ if (flags & FLAG_DE_STORAGE) {
+ auto path = create_data_user_de_package_path(uuid, userid, pkgname);
+ if (fs_prepare_dir_strict(path.c_str(), 0751, uid, uid) == -1) {
+ PLOG(ERROR) << "Failed to prepare " << path;
+ return -1;
+ }
+ if (selinux_android_setfilecon(path.c_str(), pkgname, seinfo, uid) < 0) {
+ PLOG(ERROR) << "Failed to setfilecon " << path;
+ return -1;
+ }
}
-
return 0;
}
-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));
+int clear_app_data(const char *uuid, const char *pkgname, userid_t userid, int flags) {
+ std::string suffix = "";
+ if (flags & FLAG_CLEAR_CACHE_ONLY) {
+ suffix = CACHE_DIR_POSTFIX;
+ } else if (flags & FLAG_CLEAR_CODE_CACHE_ONLY) {
+ suffix = CODE_CACHE_DIR_POSTFIX;
+ }
int res = 0;
- res |= delete_dir_contents(ce_package_path);
- // TODO: include result once 25796509 is fixed
- 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 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));
-
- 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 (flags & FLAG_CE_STORAGE) {
+ auto path = create_data_user_package_path(uuid, userid, pkgname) + suffix;
+ if (access(path.c_str(), F_OK) == 0) {
+ res |= delete_dir_contents(path);
+ }
}
- 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 (flags & FLAG_DE_STORAGE) {
+ auto path = create_data_user_de_package_path(uuid, userid, pkgname) + suffix;
+ if (access(path.c_str(), F_OK) == 0) {
+ res |= delete_dir_contents(path);
+ }
}
+ return res;
+}
- 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);
- // TODO: include result once 25796509 is fixed
- return 0;
+int destroy_app_data(const char *uuid, const char *pkgname, userid_t userid, int flags) {
+ int res = 0;
+ if (flags & FLAG_CE_STORAGE) {
+ res |= delete_dir_contents_and_dir(
+ create_data_user_package_path(uuid, userid, pkgname));
}
- 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);
- // TODO: include result once 25796509 is fixed
- return 0;
+ if (flags & FLAG_DE_STORAGE) {
+ res |= delete_dir_contents_and_dir(
+ create_data_user_de_package_path(uuid, userid, pkgname));
}
-
- return 0;
+ return res;
}
-int copy_complete_app(const char *from_uuid, const char *to_uuid,
- const char *package_name, const char *data_app_name, appid_t appid,
- const char* seinfo) {
+int move_complete_app(const char *from_uuid, const char *to_uuid, const char *package_name,
+ const char *data_app_name, appid_t appid, const char* seinfo) {
std::vector<userid_t> users = get_known_users(from_uuid);
// Copy app
goto fail;
}
- uid_t uid = multiuser_get_uid(user, appid);
- if (make_user_data(to_uuid, package_name, uid, user, seinfo) != 0) {
+ if (create_app_data(to_uuid, package_name, user, FLAG_CE_STORAGE | FLAG_DE_STORAGE,
+ appid, seinfo) != 0) {
LOG(ERROR) << "Failed to create package target " << to;
goto fail;
}
<< ": status " << rc;
goto fail;
}
- }
- if (restorecon_data(to_uuid, package_name, seinfo, multiuser_get_uid(0, appid)) != 0) {
- LOG(ERROR) << "Failed to restorecon";
- goto fail;
+ if (restorecon_app_data(to_uuid, package_name, user, FLAG_CE_STORAGE | FLAG_DE_STORAGE,
+ appid, seinfo) != 0) {
+ LOG(ERROR) << "Failed to restorecon";
+ goto fail;
+ }
}
// We let the framework scan the new location and persist that before
return res;
}
-int delete_cache(const char *uuid, const char *pkgname, userid_t userid)
-{
- std::string _cachedir(
- create_data_user_package_path(uuid, userid, pkgname) + 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 *uuid, const char *pkgname, userid_t userid)
-{
- std::string _codecachedir(
- create_data_user_package_path(uuid, userid, pkgname) + CODE_CACHE_DIR_POSTFIX);
- const char* codecachedir = _codecachedir.c_str();
-
- struct stat s;
-
- /* it's okay if code cache is missing */
- if (lstat(codecachedir, &s) == -1 && errno == ENOENT) {
- return 0;
- }
-
- /* delete contents, not the directory, no exceptions */
- return delete_dir_contents(codecachedir, 0, NULL);
-}
-
/* Try to ensure free_size bytes of storage are available.
* Returns 0 on success.
* This is rather simple-minded because doing a full LRU would
return data_disk_free(data_path) >= free_size ? 0 : -1;
}
-int move_dex(const char *src, const char *dst, const char *instruction_set)
-{
- char src_dex[PKG_PATH_MAX];
- char dst_dex[PKG_PATH_MAX];
-
- if (validate_apk_path(src)) {
- ALOGE("invalid apk path '%s' (bad prefix)\n", src);
- return -1;
- }
- if (validate_apk_path(dst)) {
- ALOGE("invalid apk path '%s' (bad prefix)\n", dst);
- return -1;
- }
-
- if (!create_cache_path(src_dex, src, instruction_set)) return -1;
- if (!create_cache_path(dst_dex, dst, instruction_set)) return -1;
-
- ALOGV("move %s -> %s\n", src_dex, dst_dex);
- if (rename(src_dex, dst_dex) < 0) {
- ALOGE("Couldn't move %s: %s\n", src_dex, strerror(errno));
- return -1;
- } else {
- return 0;
- }
-}
-
int rm_dex(const char *path, const char *instruction_set)
{
char dex_path[PKG_PATH_MAX];
}
}
-int get_size(const char *uuid, const char *pkgname, int 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 get_app_size(const char *uuid, const char *pkgname, int userid, int flags,
+ 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) {
DIR *d;
int dfd;
struct dirent *de;
for (auto user : users) {
// TODO: handle user_de directories
+ if (!(flags & FLAG_CE_STORAGE)) continue;
+
std::string _pkgdir(create_data_user_package_path(uuid, user, pkgname));
const char* pkgdir = _pkgdir.c_str();
return -1;
}
-int restorecon_data(const char* uuid, const char* pkgName, const char* seinfo, appid_t appid) {
+int restorecon_app_data(const char* uuid, const char* pkgName, userid_t userid, int flags,
+ appid_t appid, const char* seinfo) {
int res = 0;
// SELINUX_ANDROID_RESTORECON_DATADATA flag is set by libselinux. Not needed here.
- unsigned int flags = SELINUX_ANDROID_RESTORECON_RECURSE;
+ unsigned int seflags = SELINUX_ANDROID_RESTORECON_RECURSE;
if (!pkgName || !seinfo) {
ALOGE("Package name or seinfo tag is null when trying to restorecon.");
return -1;
}
- // 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);
-
- 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;
+ uid_t uid = multiuser_get_uid(userid, appid);
+ if (flags & FLAG_CE_STORAGE) {
+ auto path = create_data_user_package_path(uuid, userid, pkgName);
+ if (selinux_android_restorecon_pkgdir(path.c_str(), seinfo, uid, seflags) < 0) {
+ PLOG(ERROR) << "restorecon failed for " << 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;
+ }
+ if (flags & FLAG_DE_STORAGE) {
+ auto path = create_data_user_de_package_path(uuid, userid, pkgName);
+ if (selinux_android_restorecon_pkgdir(path.c_str(), seinfo, uid, seflags) < 0) {
+ PLOG(ERROR) << "restorecon failed for " << path;
// TODO: include result once 25796509 is fixed
}
}
namespace android {
namespace installd {
-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 *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 copy_complete_app(const char* from_uuid, const char *to_uuid,
- const char *package_name, const char *data_app_name, appid_t appid,
- const char* seinfo);
+int create_app_data(const char *uuid, const char *pkgname, userid_t userid, int flags,
+ appid_t appid, const char* seinfo);
+int restorecon_app_data(const char* uuid, const char* pkgName, userid_t userid, int flags,
+ appid_t appid, const char* seinfo);
+int clear_app_data(const char *uuid, const char *pkgname, userid_t userid, int flags);
+int destroy_app_data(const char *uuid, const char *pkgname, userid_t userid, int flags);
+
+int move_complete_app(const char* from_uuid, const char *to_uuid, const char *package_name,
+ const char *data_app_name, appid_t appid, const char* seinfo);
+
+int get_app_size(const char *uuid, const char *pkgname, int userid, int flags,
+ 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 make_user_config(userid_t userid);
int delete_user(const char *uuid, 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 *uuid, const char *pkgname, int 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(const char *uuid, int64_t free_size);
int dexopt(const char *apk_path, uid_t uid, const char *pkgName, const char *instruction_set,
int dexopt_needed, const char* oat_dir, int dexopt_flags);
int movefiles();
int linklib(const char* uuid, const char* pkgname, const char* asecLibDir, int userId);
int idmap(const char *target_path, const char *overlay_path, 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 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);
} // namespace installd
#include <selinux/android.h>
#include <selinux/avc.h>
#include <sys/capability.h>
+#include <sys/fsuid.h>
#include <sys/prctl.h>
#include <sys/socket.h>
#include <sys/stat.h>
#define TOKEN_MAX 16 /* max number of arguments in buffer */
#define REPLY_MAX 256 /* largest reply allowed */
+#define DEBUG_FBE 0
namespace android {
namespace installd {
return 0;
}
-static int do_install(char **arg, char reply[REPLY_MAX] ATTRIBUTE_UNUSED)
-{
- return install(parse_null(arg[0]), arg[1], atoi(arg[2]), atoi(arg[3]), arg[4]); /* uuid, pkgname, uid, gid, seinfo */
+static int do_create_app_data(char **arg, char reply[REPLY_MAX] ATTRIBUTE_UNUSED) {
+ /* const char *uuid, const char *pkgname, userid_t userid, int flags,
+ appid_t appid, const char* seinfo */
+ return create_app_data(parse_null(arg[0]), arg[1], atoi(arg[2]), atoi(arg[3]), atoi(arg[4]), arg[5]);
+}
+
+static int do_restorecon_app_data(char **arg, char reply[REPLY_MAX] ATTRIBUTE_UNUSED) {
+ /* const char* uuid, const char* pkgName, userid_t userid, int flags,
+ appid_t appid, const char* seinfo */
+ return restorecon_app_data(parse_null(arg[0]), arg[1], atoi(arg[2]), atoi(arg[3]), atoi(arg[4]), arg[5]);
+}
+
+static int do_clear_app_data(char **arg, char reply[REPLY_MAX] ATTRIBUTE_UNUSED) {
+ /* const char *uuid, const char *pkgname, userid_t userid, int flags */
+ return clear_app_data(parse_null(arg[0]), arg[1], atoi(arg[2]), atoi(arg[3]));
+}
+
+static int do_destroy_app_data(char **arg, char reply[REPLY_MAX] ATTRIBUTE_UNUSED) {
+ /* const char *uuid, const char *pkgname, userid_t userid, int flags */
+ return destroy_app_data(parse_null(arg[0]), arg[1], atoi(arg[2]), atoi(arg[3]));
}
static int do_dexopt(char **arg, char reply[REPLY_MAX] ATTRIBUTE_UNUSED)
return mark_boot_complete(arg[0] /* instruction set */);
}
-static int do_move_dex(char **arg, char reply[REPLY_MAX] ATTRIBUTE_UNUSED)
-{
- return move_dex(arg[0], arg[1], arg[2]); /* src, dst, instruction_set */
-}
-
static int do_rm_dex(char **arg, char reply[REPLY_MAX] ATTRIBUTE_UNUSED)
{
return rm_dex(arg[0], arg[1]); /* pkgname, instruction_set */
}
-static int do_remove(char **arg, char reply[REPLY_MAX] ATTRIBUTE_UNUSED)
-{
- return uninstall(parse_null(arg[0]), arg[1], atoi(arg[2])); /* uuid, pkgname, userid */
-}
-
-static int do_fixuid(char **arg, char reply[REPLY_MAX] ATTRIBUTE_UNUSED)
-{
- return fix_uid(parse_null(arg[0]), arg[1], atoi(arg[2]), atoi(arg[3])); /* uuid, pkgname, uid, gid */
-}
-
static int do_free_cache(char **arg, char reply[REPLY_MAX] ATTRIBUTE_UNUSED) /* TODO int:free_size */
{
return free_cache(parse_null(arg[0]), (int64_t)atoll(arg[1])); /* uuid, free_size */
}
-static int do_rm_cache(char **arg, char reply[REPLY_MAX] ATTRIBUTE_UNUSED)
-{
- return delete_cache(parse_null(arg[0]), arg[1], atoi(arg[2])); /* uuid, pkgname, userid */
-}
-
-static int do_rm_code_cache(char **arg, char reply[REPLY_MAX] ATTRIBUTE_UNUSED)
-{
- return delete_code_cache(parse_null(arg[0]), arg[1], atoi(arg[2])); /* uuid, pkgname, userid */
-}
-
-static int do_get_size(char **arg, char reply[REPLY_MAX])
-{
+static int do_get_app_size(char **arg, char reply[REPLY_MAX]) {
int64_t codesize = 0;
int64_t datasize = 0;
int64_t cachesize = 0;
int64_t asecsize = 0;
int res = 0;
- /* uuid, pkgdir, userid, apkpath */
- res = get_size(parse_null(arg[0]), arg[1], atoi(arg[2]), arg[3], arg[4], arg[5], arg[6],
- arg[7], &codesize, &datasize, &cachesize, &asecsize);
+ /* const char *uuid, const char *pkgname, userid_t userid, int flags,
+ const char *apkpath, const char *libdirpath, const char *fwdlock_apkpath,
+ const char *asecpath, const char *instruction_set */
+ res = get_app_size(parse_null(arg[0]), arg[1], atoi(arg[2]), atoi(arg[3]), arg[4], arg[5],
+ arg[6], arg[7], arg[8], &codesize, &datasize, &cachesize, &asecsize);
/*
* Each int64_t can take up 22 characters printed out. Make sure it
return res;
}
-static int do_rm_user_data(char **arg, char reply[REPLY_MAX] ATTRIBUTE_UNUSED)
-{
- return delete_user_data(parse_null(arg[0]), arg[1], atoi(arg[2])); /* uuid, pkgname, userid */
-}
-
-static int do_cp_complete_app(char **arg, char reply[REPLY_MAX] ATTRIBUTE_UNUSED)
-{
- // from_uuid, to_uuid, package_name, data_app_name, appid, seinfo
- return copy_complete_app(parse_null(arg[0]), parse_null(arg[1]), arg[2], arg[3], atoi(arg[4]), arg[5]);
-}
-
-static int do_mk_user_data(char **arg, char reply[REPLY_MAX] ATTRIBUTE_UNUSED)
-{
- return make_user_data(parse_null(arg[0]), arg[1], atoi(arg[2]), atoi(arg[3]), arg[4]);
- /* uuid, pkgname, uid, userid, seinfo */
+static int do_move_complete_app(char **arg, char reply[REPLY_MAX] ATTRIBUTE_UNUSED) {
+ /* const char* from_uuid, const char *to_uuid, const char *package_name,
+ const char *data_app_name, appid_t appid, const char* seinfo */
+ return move_complete_app(parse_null(arg[0]), parse_null(arg[1]), arg[2], arg[3], atoi(arg[4]), arg[5]);
}
static int do_mk_user_config(char **arg, char reply[REPLY_MAX] ATTRIBUTE_UNUSED)
return idmap(arg[0], arg[1], atoi(arg[2]));
}
-static int do_restorecon_data(char **arg, char reply[REPLY_MAX] ATTRIBUTE_UNUSED)
-{
- return restorecon_data(parse_null(arg[0]), arg[1], arg[2], atoi(arg[3]));
- /* uuid, pkgName, seinfo, uid*/
-}
-
static int do_create_oat_dir(char **arg, char reply[REPLY_MAX] ATTRIBUTE_UNUSED)
{
/* oat_dir, instruction_set */
struct cmdinfo cmds[] = {
{ "ping", 0, do_ping },
- { "install", 5, do_install },
+
+ { "create_app_data", 6, do_create_app_data },
+ { "restorecon_app_data", 6, do_restorecon_app_data },
+ { "clear_app_data", 4, do_clear_app_data },
+ { "destroy_app_data", 4, do_destroy_app_data },
+ { "move_complete_app", 6, do_move_complete_app },
+ { "get_app_size", 9, do_get_app_size },
+
{ "dexopt", 7, do_dexopt },
{ "markbootcomplete", 1, do_mark_boot_complete },
- { "movedex", 3, do_move_dex },
{ "rmdex", 2, do_rm_dex },
- { "remove", 3, do_remove },
- { "fixuid", 4, do_fixuid },
{ "freecache", 2, do_free_cache },
- { "rmcache", 3, do_rm_cache },
- { "rmcodecache", 3, do_rm_code_cache },
- { "getsize", 8, do_get_size },
- { "rmuserdata", 3, do_rm_user_data },
- { "cpcompleteapp", 6, do_cp_complete_app },
{ "movefiles", 0, do_movefiles },
{ "linklib", 4, do_linklib },
- { "mkuserdata", 5, do_mk_user_data },
{ "mkuserconfig", 1, do_mk_user_config },
{ "rmuser", 2, do_rm_user },
{ "idmap", 3, do_idmap },
- { "restorecondata", 4, do_restorecon_data },
{ "createoatdir", 2, do_create_oat_dir },
{ "rmpackagedir", 1, do_rm_package_dir },
- { "linkfile", 3, do_link_file }
+ { "linkfile", 3, do_link_file },
};
static int readx(int s, void *_buf, int count)
}
fcntl(lsocket, F_SETFD, FD_CLOEXEC);
+ // Perform all filesystem access as system so that FBE emulation mode
+ // can block access using chmod 000.
+#if DEBUG_FBE
+ setfsuid(AID_SYSTEM);
+#endif
+
for (;;) {
alen = sizeof(addr);
s = accept(lsocket, &addr, &alen);
constexpr size_t PKG_NAME_MAX = 128u; /* largest allowed package name */
constexpr size_t PKG_PATH_MAX = 256u; /* max size of any path we use */
+constexpr int FLAG_DE_STORAGE = 1 << 0;
+constexpr int FLAG_CE_STORAGE = 1 << 1;
+constexpr int FLAG_CLEAR_CACHE_ONLY = 1 << 2;
+constexpr int FLAG_CLEAR_CODE_CACHE_ONLY = 1 << 3;
+
/* dexopt needed flags matching those in dalvik.system.DexFile */
constexpr int DEXOPT_DEX2OAT_NEEDED = 1;
constexpr int DEXOPT_PATCHOAT_NEEDED = 2;