diff options
author | 2016-02-06 19:46:09 -0700 | |
---|---|---|
committer | 2016-02-06 20:17:47 -0700 | |
commit | cc6281cf8146cddb8ace7cbd58c67321639c1520 (patch) | |
tree | 0cf32fa461f00b148a110aadebe37a103067b603 | |
parent | 6a45fb96bcc67f8266ec4c3aac513d64cd751610 (diff) |
Migrate default app data on non-FBE devices.
When a system app requests "forceDeviceEncrypted" they expect their
default app storage to point at a consistent location regardless of
device FBE support. So when booting upgraded non-FBE devices, we
may need to migrate any data from CE to DE. Note that on non-FBE
devices these are just semantic locations with identical protection.
This migration *only* works for non-FBE devices; changing
forceDeviceEncrypted flags on an FBE device always requires a full
data wipe.
Bug: 26668510
Change-Id: I8bd5b8ba882e6bd067c0381041b27c35d6e47788
-rw-r--r-- | cmds/dumpstate/dumpstate.rc | 4 | ||||
-rw-r--r-- | cmds/installd/commands.cpp | 43 | ||||
-rw-r--r-- | cmds/installd/commands.h | 1 | ||||
-rw-r--r-- | cmds/installd/installd.cpp | 6 |
4 files changed, 51 insertions, 3 deletions
diff --git a/cmds/dumpstate/dumpstate.rc b/cmds/dumpstate/dumpstate.rc index d1b7f8c88b..96232c4289 100644 --- a/cmds/dumpstate/dumpstate.rc +++ b/cmds/dumpstate/dumpstate.rc @@ -13,7 +13,7 @@ service dumpstate /system/bin/dumpstate -s # user interface (like displaying progress and allowing user to enter details). # It's typically triggered by the power button or developer settings. service bugreportplus /system/bin/dumpstate -d -B -P -z \ - -o /data/data/com.android.shell/files/bugreports/bugreport + -o /data/user_de/0/com.android.shell/files/bugreports/bugreport class main disabled oneshot @@ -25,7 +25,7 @@ service bugreportplus /system/bin/dumpstate -d -B -P -z \ # it will disable vibrations, screenshot taking and will not track progress or # allow user to enter any details service bugreportremote /system/bin/dumpstate -d -q -B -R -z \ - -o /data/data/com.android.shell/files/bugreports/remote/bugreport + -o /data/user_de/0/com.android.shell/files/bugreports/remote/bugreport class main disabled oneshot diff --git a/cmds/installd/commands.cpp b/cmds/installd/commands.cpp index df80eb6506..e54407cf91 100644 --- a/cmds/installd/commands.cpp +++ b/cmds/installd/commands.cpp @@ -23,6 +23,8 @@ #include <sys/file.h> #include <sys/resource.h> #include <sys/stat.h> +#include <sys/types.h> +#include <sys/xattr.h> #include <unistd.h> #include <android-base/stringprintf.h> @@ -49,7 +51,8 @@ using android::base::StringPrintf; namespace android { namespace installd { -static const char* kCpPath = "/system/bin/cp"; +static constexpr const char* kCpPath = "/system/bin/cp"; +static constexpr const char* kXattrDefault = "user.default"; #define MIN_RESTRICTED_HOME_SDK_VERSION 24 // > M @@ -84,6 +87,44 @@ int create_app_data(const char *uuid, const char *pkgname, userid_t userid, int return 0; } +int migrate_app_data(const char *uuid, const char *pkgname, userid_t userid, int flags) { + // This method only exists to upgrade system apps that have requested + // forceDeviceEncrypted, so their default storage always lives in a + // consistent location. This only works on non-FBE devices, since we + // never want to risk exposing data on a device with real CE/DE storage. + + auto ce_path = create_data_user_package_path(uuid, userid, pkgname); + auto de_path = create_data_user_de_package_path(uuid, userid, pkgname); + + // If neither directory is marked as default, assume CE is default + if (getxattr(ce_path.c_str(), kXattrDefault, nullptr, 0) == -1 + && getxattr(de_path.c_str(), kXattrDefault, nullptr, 0) == -1) { + if (setxattr(ce_path.c_str(), kXattrDefault, nullptr, 0, 0) != 0) { + PLOG(ERROR) << "Failed to mark default storage " << ce_path; + return -1; + } + } + + // Migrate default data location if needed + auto target = (flags & FLAG_STORAGE_DE) ? de_path : ce_path; + auto source = (flags & FLAG_STORAGE_DE) ? ce_path : de_path; + + if (getxattr(target.c_str(), kXattrDefault, nullptr, 0) == -1) { + LOG(WARNING) << "Requested default storage " << target + << " is not active; migrating from " << source; + if (delete_dir_contents_and_dir(target) != 0) { + PLOG(ERROR) << "Failed to delete"; + return -1; + } + if (rename(source.c_str(), target.c_str()) != 0) { + PLOG(ERROR) << "Failed to rename"; + return -1; + } + } + + return 0; +} + int clear_app_data(const char *uuid, const char *pkgname, userid_t userid, int flags) { std::string suffix = ""; if (flags & FLAG_CLEAR_CACHE_ONLY) { diff --git a/cmds/installd/commands.h b/cmds/installd/commands.h index 53a789fd3c..fe03397c5f 100644 --- a/cmds/installd/commands.h +++ b/cmds/installd/commands.h @@ -32,6 +32,7 @@ int create_app_data(const char *uuid, const char *pkgname, userid_t userid, int appid_t appid, const char* seinfo, int target_sdk_version); int restorecon_app_data(const char* uuid, const char* pkgName, userid_t userid, int flags, appid_t appid, const char* seinfo); +int migrate_app_data(const char *uuid, const char *pkgname, userid_t userid, int flags); 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); diff --git a/cmds/installd/installd.cpp b/cmds/installd/installd.cpp index c0ae5b7905..63290a9ba8 100644 --- a/cmds/installd/installd.cpp +++ b/cmds/installd/installd.cpp @@ -201,6 +201,11 @@ static int do_restorecon_app_data(char **arg, char reply[REPLY_MAX] ATTRIBUTE_UN return restorecon_app_data(parse_null(arg[0]), arg[1], atoi(arg[2]), atoi(arg[3]), atoi(arg[4]), arg[5]); } +static int do_migrate_app_data(char **arg, char reply[REPLY_MAX] ATTRIBUTE_UNUSED) { + /* const char *uuid, const char *pkgname, userid_t userid, int flags */ + return migrate_app_data(parse_null(arg[0]), arg[1], atoi(arg[2]), atoi(arg[3])); +} + 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])); @@ -342,6 +347,7 @@ struct cmdinfo cmds[] = { { "create_app_data", 7, do_create_app_data }, { "restorecon_app_data", 6, do_restorecon_app_data }, + { "migrate_app_data", 4, do_migrate_app_data }, { "clear_app_data", 4, do_clear_app_data }, { "destroy_app_data", 4, do_destroy_app_data }, { "move_complete_app", 7, do_move_complete_app }, |