Make encryption action an argument to mkdir

FscryptSetDirectoryPolicy no longer tries to infer the action from the
filename. Well mostly; it still assumes top-level directories in /data
should be encrypted unless the mkdir arguments say otherwise, but
it warns.

Bug: 26641735
Test: boot, check log messages
Change-Id: Id6d2cea7fb856f17323897d85cf6190c981b443c
This commit is contained in:
Paul Crowley 2019-10-28 07:55:03 -07:00
parent 4645210097
commit 68258e8444
9 changed files with 290 additions and 197 deletions

View file

@ -505,12 +505,23 @@ Commands
> Used to mark the point right after /data is mounted. Used to implement the
`class_reset_post_data` and `class_start_post_data` commands.
`mkdir <path> [mode] [owner] [group]`
`mkdir <path> [<mode>] [<owner>] [<group>] [encryption=<action>] [key=<key>]`
> Create a directory at _path_, optionally with the given mode, owner, and
group. If not provided, the directory is created with permissions 755 and
owned by the root user and root group. If provided, the mode, owner and group
will be updated if the directory exists already.
> _action_ can be one of:
* `None`: take no encryption action; directory will be encrypted if parent is.
* `Require`: encrypt directory, abort boot process if encryption fails
* `Attempt`: try to set an encryption policy, but continue if it fails
* `DeleteIfNecessary`: recursively delete directory if necessary to set
encryption policy.
> _key_ can be one of:
* `ref`: use the systemwide DE key
* `per_boot_ref`: use the key freshly generated on each boot.
`mount_all <fstab> [ <path> ]\* [--<option>]`
> Calls fs\_mgr\_mount\_all on the given fs\_mgr-format fstab with optional
options "early" and "late".

View file

@ -364,67 +364,52 @@ static Result<void> do_interface_stop(const BuiltinArguments& args) {
return {};
}
// mkdir <path> [mode] [owner] [group]
// mkdir <path> [mode] [owner] [group] [<option> ...]
static Result<void> do_mkdir(const BuiltinArguments& args) {
mode_t mode = 0755;
Result<uid_t> uid = -1;
Result<gid_t> gid = -1;
switch (args.size()) {
case 5:
gid = DecodeUid(args[4]);
if (!gid) {
return Error() << "Unable to decode GID for '" << args[4] << "': " << gid.error();
}
FALLTHROUGH_INTENDED;
case 4:
uid = DecodeUid(args[3]);
if (!uid) {
return Error() << "Unable to decode UID for '" << args[3] << "': " << uid.error();
}
FALLTHROUGH_INTENDED;
case 3:
mode = std::strtoul(args[2].c_str(), 0, 8);
FALLTHROUGH_INTENDED;
case 2:
break;
default:
return Error() << "Unexpected argument count: " << args.size();
auto options = ParseMkdir(args.args);
if (!options) return options.error();
std::string ref_basename;
if (options->ref_option == "ref") {
ref_basename = fscrypt_key_ref;
} else if (options->ref_option == "per_boot_ref") {
ref_basename = fscrypt_key_per_boot_ref;
} else {
return Error() << "Unknown key option: '" << options->ref_option << "'";
}
std::string target = args[1];
struct stat mstat;
if (lstat(target.c_str(), &mstat) != 0) {
if (lstat(options->target.c_str(), &mstat) != 0) {
if (errno != ENOENT) {
return ErrnoError() << "lstat() failed on " << target;
return ErrnoError() << "lstat() failed on " << options->target;
}
if (!make_dir(target, mode)) {
return ErrnoErrorIgnoreEnoent() << "mkdir() failed on " << target;
if (!make_dir(options->target, options->mode)) {
return ErrnoErrorIgnoreEnoent() << "mkdir() failed on " << options->target;
}
if (lstat(target.c_str(), &mstat) != 0) {
return ErrnoError() << "lstat() failed on new " << target;
if (lstat(options->target.c_str(), &mstat) != 0) {
return ErrnoError() << "lstat() failed on new " << options->target;
}
}
if (!S_ISDIR(mstat.st_mode)) {
return Error() << "Not a directory on " << target;
return Error() << "Not a directory on " << options->target;
}
bool needs_chmod = (mstat.st_mode & ~S_IFMT) != mode;
if ((*uid != static_cast<uid_t>(-1) && *uid != mstat.st_uid) ||
(*gid != static_cast<gid_t>(-1) && *gid != mstat.st_gid)) {
if (lchown(target.c_str(), *uid, *gid) == -1) {
return ErrnoError() << "lchown failed on " << target;
bool needs_chmod = (mstat.st_mode & ~S_IFMT) != options->mode;
if ((options->uid != static_cast<uid_t>(-1) && options->uid != mstat.st_uid) ||
(options->gid != static_cast<gid_t>(-1) && options->gid != mstat.st_gid)) {
if (lchown(options->target.c_str(), options->uid, options->gid) == -1) {
return ErrnoError() << "lchown failed on " << options->target;
}
// chown may have cleared S_ISUID and S_ISGID, chmod again
needs_chmod = true;
}
if (needs_chmod) {
if (fchmodat(AT_FDCWD, target.c_str(), mode, AT_SYMLINK_NOFOLLOW) == -1) {
return ErrnoError() << "fchmodat() failed on " << target;
if (fchmodat(AT_FDCWD, options->target.c_str(), options->mode, AT_SYMLINK_NOFOLLOW) == -1) {
return ErrnoError() << "fchmodat() failed on " << options->target;
}
}
if (fscrypt_is_native()) {
if (fscrypt_set_directory_policy(target)) {
if (!FscryptSetDirectoryPolicy(ref_basename, options->fscrypt_action, options->target)) {
return reboot_into_recovery(
{"--prompt_and_wipe_data", "--reason=set_policy_failed:"s + target});
{"--prompt_and_wipe_data", "--reason=set_policy_failed:"s + options->target});
}
}
return {};
@ -589,8 +574,8 @@ static Result<void> queue_fs_event(int code) {
return reboot_into_recovery(options);
/* If reboot worked, there is no return. */
} else if (code == FS_MGR_MNTALL_DEV_FILE_ENCRYPTED) {
if (fscrypt_install_keyring()) {
return Error() << "fscrypt_install_keyring() failed";
if (!FscryptInstallKeyring()) {
return Error() << "FscryptInstallKeyring() failed";
}
property_set("ro.crypto.state", "encrypted");
property_set("ro.crypto.type", "file");
@ -600,8 +585,8 @@ static Result<void> queue_fs_event(int code) {
ActionManager::GetInstance().QueueEventTrigger("nonencrypted");
return {};
} else if (code == FS_MGR_MNTALL_DEV_IS_METADATA_ENCRYPTED) {
if (fscrypt_install_keyring()) {
return Error() << "fscrypt_install_keyring() failed";
if (!FscryptInstallKeyring()) {
return Error() << "FscryptInstallKeyring() failed";
}
property_set("ro.crypto.state", "encrypted");
property_set("ro.crypto.type", "file");
@ -611,8 +596,8 @@ static Result<void> queue_fs_event(int code) {
ActionManager::GetInstance().QueueEventTrigger("nonencrypted");
return {};
} else if (code == FS_MGR_MNTALL_DEV_NEEDS_METADATA_ENCRYPTION) {
if (fscrypt_install_keyring()) {
return Error() << "fscrypt_install_keyring() failed";
if (!FscryptInstallKeyring()) {
return Error() << "FscryptInstallKeyring() failed";
}
property_set("ro.crypto.state", "encrypted");
property_set("ro.crypto.type", "file");
@ -1257,7 +1242,7 @@ const BuiltinFunctionMap& GetBuiltinFunctionMap() {
{"load_system_props", {0, 0, {false, do_load_system_props}}},
{"loglevel", {1, 1, {false, do_loglevel}}},
{"mark_post_data", {0, 0, {false, do_mark_post_data}}},
{"mkdir", {1, 4, {true, do_mkdir}}},
{"mkdir", {1, 6, {true, do_mkdir}}},
// TODO: Do mount operations in vendor_init.
// mount_all is currently too complex to run in vendor_init as it queues action triggers,
// imports rc scripts, etc. It should be simplified and run in vendor_init context.

View file

@ -121,22 +121,10 @@ Result<void> check_loglevel(const BuiltinArguments& args) {
}
Result<void> check_mkdir(const BuiltinArguments& args) {
if (args.size() >= 4) {
if (!args[3].empty()) {
auto uid = DecodeUid(args[3]);
if (!uid) {
return Error() << "Unable to decode UID for '" << args[3] << "': " << uid.error();
}
}
if (args.size() == 5 && !args[4].empty()) {
auto gid = DecodeUid(args[4]);
if (!gid) {
return Error() << "Unable to decode GID for '" << args[4] << "': " << gid.error();
}
}
auto options = ParseMkdir(args.args);
if (!options) {
return options.error();
}
return {};
}

View file

@ -41,19 +41,15 @@
using namespace android::fscrypt;
static int set_policy_on(const std::string& ref_basename, const std::string& dir);
int fscrypt_install_keyring() {
bool FscryptInstallKeyring() {
key_serial_t device_keyring = add_key("keyring", "fscrypt", 0, 0, KEY_SPEC_SESSION_KEYRING);
if (device_keyring == -1) {
PLOG(ERROR) << "Failed to create keyring";
return -1;
return false;
}
LOG(INFO) << "Keyring created with id " << device_keyring << " in process " << getpid();
return 0;
return true;
}
// TODO(b/139378601): use a single central implementation of this.
@ -97,102 +93,57 @@ static void delete_dir_contents(const std::string& dir) {
}
}
int fscrypt_set_directory_policy(const std::string& dir) {
const std::string prefix = "/data/";
if (!android::base::StartsWith(dir, prefix)) {
return 0;
}
// Special-case /data/media/obb per b/64566063
if (dir == "/data/media/obb") {
// Try to set policy on this directory, but if it is non-empty this may fail.
set_policy_on(fscrypt_key_ref, dir);
return 0;
}
// Only set policy on first level /data directories
// To make this less restrictive, consider using a policy file.
// However this is overkill for as long as the policy is simply
// to apply a global policy to all /data folders created via makedir
if (dir.find_first_of('/', prefix.size()) != std::string::npos) {
return 0;
}
// Special case various directories that must not be encrypted,
// often because their subdirectories must be encrypted.
// This isn't a nice way to do this, see b/26641735
std::vector<std::string> directories_to_exclude = {
"lost+found",
"system_ce", "system_de",
"misc_ce", "misc_de",
"vendor_ce", "vendor_de",
"media",
"data", "user", "user_de",
"apex", "preloads", "app-staging",
"gsi",
};
for (const auto& d : directories_to_exclude) {
if ((prefix + d) == dir) {
LOG(INFO) << "Not setting policy on " << dir;
return 0;
}
}
std::vector<std::string> per_boot_directories = {
"per_boot",
};
for (const auto& d : per_boot_directories) {
if ((prefix + d) == dir) {
LOG(INFO) << "Setting per_boot key on " << dir;
return set_policy_on(fscrypt_key_per_boot_ref, dir);
}
}
int err = set_policy_on(fscrypt_key_ref, dir);
if (err == 0) {
return 0;
}
// Empty these directories if policy setting fails.
std::vector<std::string> wipe_on_failure = {
"rollback", "rollback-observer", // b/139193659
};
for (const auto& d : wipe_on_failure) {
if ((prefix + d) == dir) {
LOG(ERROR) << "Setting policy failed, deleting: " << dir;
delete_dir_contents(dir);
err = set_policy_on(fscrypt_key_ref, dir);
break;
}
}
return err;
}
// Set an encryption policy on the given directory. The policy (key reference
// Look up an encryption policy The policy (key reference
// and encryption options) to use is read from files that were written by vold.
static int set_policy_on(const std::string& ref_basename, const std::string& dir) {
EncryptionPolicy policy;
static bool LookupPolicy(const std::string& ref_basename, EncryptionPolicy* policy) {
std::string ref_filename = std::string("/data") + ref_basename;
if (!android::base::ReadFileToString(ref_filename, &policy.key_raw_ref)) {
LOG(ERROR) << "Unable to read system policy to set on " << dir;
return -1;
if (!android::base::ReadFileToString(ref_filename, &policy->key_raw_ref)) {
LOG(ERROR) << "Unable to read system policy with name " << ref_filename;
return false;
}
auto options_filename = std::string("/data") + fscrypt_key_mode;
std::string options_string;
if (!android::base::ReadFileToString(options_filename, &options_string)) {
LOG(ERROR) << "Cannot read encryption options string";
return -1;
return false;
}
if (!ParseOptions(options_string, &policy.options)) {
if (!ParseOptions(options_string, &policy->options)) {
LOG(ERROR) << "Invalid encryption options string: " << options_string;
return -1;
return false;
}
return true;
}
static bool EnsurePolicyOrLog(const EncryptionPolicy& policy, const std::string& dir) {
if (!EnsurePolicy(policy, dir)) {
std::string ref_hex;
BytesToHex(policy.key_raw_ref, &ref_hex);
LOG(ERROR) << "Setting " << ref_hex << " policy on " << dir << " failed!";
return -1;
return false;
}
return 0;
return true;
}
static bool SetPolicyOn(const std::string& ref_basename, const std::string& dir) {
EncryptionPolicy policy;
if (!LookupPolicy(ref_basename, &policy)) return false;
if (!EnsurePolicyOrLog(policy, dir)) return false;
return true;
}
bool FscryptSetDirectoryPolicy(const std::string& ref_basename, FscryptAction action,
const std::string& dir) {
if (action == FscryptAction::kNone) {
return true;
}
if (SetPolicyOn(ref_basename, dir) || action == FscryptAction::kAttempt) {
return true;
}
if (action == FscryptAction::kDeleteIfNecessary) {
LOG(ERROR) << "Setting policy failed, deleting: " << dir;
delete_dir_contents(dir);
return SetPolicyOn(ref_basename, dir);
}
return false;
}

View file

@ -18,5 +18,13 @@
#include <string>
int fscrypt_install_keyring();
int fscrypt_set_directory_policy(const std::string& dir);
enum class FscryptAction {
kNone,
kAttempt,
kRequire,
kDeleteIfNecessary,
};
bool FscryptInstallKeyring();
bool FscryptSetDirectoryPolicy(const std::string& ref_basename, FscryptAction action,
const std::string& dir);

View file

@ -434,6 +434,142 @@ Result<void> IsLegalPropertyValue(const std::string& name, const std::string& va
return {};
}
static FscryptAction FscryptInferAction(const std::string& dir) {
const std::string prefix = "/data/";
if (!android::base::StartsWith(dir, prefix)) {
return FscryptAction::kNone;
}
// Special-case /data/media/obb per b/64566063
if (dir == "/data/media/obb") {
// Try to set policy on this directory, but if it is non-empty this may fail.
return FscryptAction::kAttempt;
}
// Only set policy on first level /data directories
// To make this less restrictive, consider using a policy file.
// However this is overkill for as long as the policy is simply
// to apply a global policy to all /data folders created via makedir
if (dir.find_first_of('/', prefix.size()) != std::string::npos) {
return FscryptAction::kNone;
}
// Special case various directories that must not be encrypted,
// often because their subdirectories must be encrypted.
// This isn't a nice way to do this, see b/26641735
std::vector<std::string> directories_to_exclude = {
"lost+found", "system_ce", "system_de", "misc_ce", "misc_de",
"vendor_ce", "vendor_de", "media", "data", "user",
"user_de", "apex", "preloads", "app-staging", "gsi",
};
for (const auto& d : directories_to_exclude) {
if ((prefix + d) == dir) {
return FscryptAction::kNone;
}
}
// Empty these directories if policy setting fails.
std::vector<std::string> wipe_on_failure = {
"rollback", "rollback-observer", // b/139193659
};
for (const auto& d : wipe_on_failure) {
if ((prefix + d) == dir) {
return FscryptAction::kDeleteIfNecessary;
}
}
return FscryptAction::kRequire;
}
Result<MkdirOptions> ParseMkdir(const std::vector<std::string>& args) {
mode_t mode = 0755;
Result<uid_t> uid = -1;
Result<gid_t> gid = -1;
FscryptAction fscrypt_inferred_action = FscryptInferAction(args[1]);
FscryptAction fscrypt_action = fscrypt_inferred_action;
std::string ref_option = "ref";
bool set_option_encryption = false;
bool set_option_key = false;
for (size_t i = 2; i < args.size(); i++) {
switch (i) {
case 2:
mode = std::strtoul(args[2].c_str(), 0, 8);
break;
case 3:
uid = DecodeUid(args[3]);
if (!uid) {
return Error()
<< "Unable to decode UID for '" << args[3] << "': " << uid.error();
}
break;
case 4:
gid = DecodeUid(args[4]);
if (!gid) {
return Error()
<< "Unable to decode GID for '" << args[4] << "': " << gid.error();
}
break;
default:
auto parts = android::base::Split(args[i], "=");
if (parts.size() != 2) {
return Error() << "Can't parse option: '" << args[i] << "'";
}
auto optname = parts[0];
auto optval = parts[1];
if (optname == "encryption") {
if (set_option_encryption) {
return Error() << "Duplicated option: '" << optname << "'";
}
if (optval == "Require") {
fscrypt_action = FscryptAction::kRequire;
} else if (optval == "None") {
fscrypt_action = FscryptAction::kNone;
} else if (optval == "Attempt") {
fscrypt_action = FscryptAction::kAttempt;
} else if (optval == "DeleteIfNecessary") {
fscrypt_action = FscryptAction::kDeleteIfNecessary;
} else {
return Error() << "Unknown encryption option: '" << optval << "'";
}
set_option_encryption = true;
} else if (optname == "key") {
if (set_option_key) {
return Error() << "Duplicated option: '" << optname << "'";
}
if (optval == "ref" || optval == "per_boot_ref") {
ref_option = optval;
} else {
return Error() << "Unknown key option: '" << optval << "'";
}
set_option_key = true;
} else {
return Error() << "Unknown option: '" << args[i] << "'";
}
}
}
if (set_option_key && fscrypt_action == FscryptAction::kNone) {
return Error() << "Key option set but encryption action is none";
}
const std::string prefix = "/data/";
if (StartsWith(args[1], prefix) &&
args[1].find_first_of('/', prefix.size()) == std::string::npos) {
if (!set_option_encryption) {
LOG(WARNING) << "Top-level directory needs encryption action, eg mkdir " << args[1]
<< " <mode> <uid> <gid> encryption=Require";
}
if (fscrypt_action == FscryptAction::kNone) {
LOG(INFO) << "Not setting encryption policy on: " << args[1];
}
}
if (fscrypt_action != fscrypt_inferred_action) {
LOG(WARNING) << "Inferred action different from explicit one, expected "
<< static_cast<int>(fscrypt_inferred_action) << " but got "
<< static_cast<int>(fscrypt_action);
}
return MkdirOptions{args[1], mode, *uid, *gid, fscrypt_action, ref_option};
}
Result<std::pair<int, std::vector<std::string>>> ParseRestorecon(
const std::vector<std::string>& args) {
struct flag_type {

View file

@ -25,6 +25,7 @@
#include <android-base/chrono_utils.h>
#include "fscrypt_init_extensions.h"
#include "result.h"
using android::base::boot_clock;
@ -60,6 +61,17 @@ bool is_android_dt_value_expected(const std::string& sub_path, const std::string
bool IsLegalPropertyName(const std::string& name);
Result<void> IsLegalPropertyValue(const std::string& name, const std::string& value);
struct MkdirOptions {
std::string target;
mode_t mode;
uid_t uid;
gid_t gid;
FscryptAction fscrypt_action;
std::string ref_option;
};
Result<MkdirOptions> ParseMkdir(const std::vector<std::string>& args);
Result<std::pair<int, std::vector<std::string>>> ParseRestorecon(
const std::vector<std::string>& args);

View file

@ -486,26 +486,26 @@ on post-fs-data
# Start bootcharting as soon as possible after the data partition is
# mounted to collect more data.
mkdir /data/bootchart 0755 shell shell
mkdir /data/bootchart 0755 shell shell encryption=Require
bootchart start
# Make sure that apexd is started in the default namespace
enter_default_mount_ns
# /data/apex is now available. Start apexd to scan and activate APEXes.
mkdir /data/apex 0750 root system
mkdir /data/apex 0750 root system encryption=None
mkdir /data/apex/active 0750 root system
mkdir /data/apex/backup 0700 root system
mkdir /data/apex/hashtree 0700 root system
mkdir /data/apex/sessions 0700 root system
mkdir /data/app-staging 0750 system system
mkdir /data/app-staging 0750 system system encryption=None
start apexd
# Avoid predictable entropy pool. Carry over entropy from previous boot.
copy /data/system/entropy.dat /dev/urandom
# create basic filesystem structure
mkdir /data/misc 01771 system misc
mkdir /data/misc 01771 system misc encryption=Require
mkdir /data/misc/recovery 0770 system log
copy /data/misc/recovery/ro.build.fingerprint /data/misc/recovery/ro.build.fingerprint.1
chmod 0440 /data/misc/recovery/ro.build.fingerprint.1
@ -548,7 +548,7 @@ on post-fs-data
mkdir /data/misc/user 0771 root root
# give system access to wpa_supplicant.conf for backup and restore
chmod 0660 /data/misc/wifi/wpa_supplicant.conf
mkdir /data/local 0751 root root
mkdir /data/local 0751 root root encryption=Require
mkdir /data/misc/media 0700 media media
mkdir /data/misc/audioserver 0700 audioserver audioserver
mkdir /data/misc/cameraserver 0700 cameraserver cameraserver
@ -567,89 +567,91 @@ on post-fs-data
mkdir /data/misc/gcov 0770 root root
mkdir /data/misc/installd 0700 root root
mkdir /data/preloads 0775 system system
mkdir /data/preloads 0775 system system encryption=None
mkdir /data/vendor 0771 root root
mkdir /data/vendor_ce 0771 root root
mkdir /data/vendor_de 0771 root root
mkdir /data/vendor 0771 root root encryption=Require
mkdir /data/vendor_ce 0771 root root encryption=None
mkdir /data/vendor_de 0771 root root encryption=None
mkdir /data/vendor/hardware 0771 root root
# For security reasons, /data/local/tmp should always be empty.
# Do not place files or directories in /data/local/tmp
mkdir /data/local/tmp 0771 shell shell
mkdir /data/local/traces 0777 shell shell
mkdir /data/data 0771 system system
mkdir /data/app-private 0771 system system
mkdir /data/app-ephemeral 0771 system system
mkdir /data/app-asec 0700 root root
mkdir /data/app-lib 0771 system system
mkdir /data/app 0771 system system
mkdir /data/property 0700 root root
mkdir /data/tombstones 0771 system system
mkdir /data/data 0771 system system encryption=None
mkdir /data/app-private 0771 system system encryption=Require
mkdir /data/app-ephemeral 0771 system system encryption=Require
mkdir /data/app-asec 0700 root root encryption=Require
mkdir /data/app-lib 0771 system system encryption=Require
mkdir /data/app 0771 system system encryption=Require
mkdir /data/property 0700 root root encryption=Require
mkdir /data/tombstones 0771 system system encryption=Require
mkdir /data/vendor/tombstones 0771 root root
mkdir /data/vendor/tombstones/wifi 0771 wifi wifi
# create dalvik-cache, so as to enforce our permissions
mkdir /data/dalvik-cache 0771 root root
mkdir /data/dalvik-cache 0771 root root encryption=Require
# create the A/B OTA directory, so as to enforce our permissions
mkdir /data/ota 0771 root root
mkdir /data/ota 0771 root root encryption=Require
# create the OTA package directory. It will be accessed by GmsCore (cache
# group), update_engine and update_verifier.
mkdir /data/ota_package 0770 system cache
mkdir /data/ota_package 0770 system cache encryption=Require
# create resource-cache and double-check the perms
mkdir /data/resource-cache 0771 system system
mkdir /data/resource-cache 0771 system system encryption=Require
chown system system /data/resource-cache
chmod 0771 /data/resource-cache
# create the lost+found directories, so as to enforce our permissions
mkdir /data/lost+found 0770 root root
mkdir /data/lost+found 0770 root root encryption=None
# create directory for DRM plug-ins - give drm the read/write access to
# the following directory.
mkdir /data/drm 0770 drm drm
mkdir /data/drm 0770 drm drm encryption=Require
# create directory for MediaDrm plug-ins - give drm the read/write access to
# the following directory.
mkdir /data/mediadrm 0770 mediadrm mediadrm
mkdir /data/mediadrm 0770 mediadrm mediadrm encryption=Require
mkdir /data/anr 0775 system system
mkdir /data/anr 0775 system system encryption=Require
# NFC: create data/nfc for nv storage
mkdir /data/nfc 0770 nfc nfc
mkdir /data/nfc 0770 nfc nfc encryption=Require
mkdir /data/nfc/param 0770 nfc nfc
# Create all remaining /data root dirs so that they are made through init
# and get proper encryption policy installed
mkdir /data/backup 0700 system system
mkdir /data/ss 0700 system system
mkdir /data/backup 0700 system system encryption=Require
mkdir /data/ss 0700 system system encryption=Require
mkdir /data/system 0775 system system
mkdir /data/system 0775 system system encryption=Require
mkdir /data/system/dropbox 0700 system system
mkdir /data/system/heapdump 0700 system system
mkdir /data/system/users 0775 system system
mkdir /data/system_de 0770 system system
mkdir /data/system_ce 0770 system system
mkdir /data/system_de 0770 system system encryption=None
mkdir /data/system_ce 0770 system system encryption=None
mkdir /data/misc_de 01771 system misc
mkdir /data/misc_ce 01771 system misc
mkdir /data/misc_de 01771 system misc encryption=None
mkdir /data/misc_ce 01771 system misc encryption=None
mkdir /data/user 0711 system system
mkdir /data/user_de 0711 system system
mkdir /data/user 0711 system system encryption=None
mkdir /data/user_de 0711 system system encryption=None
symlink /data/data /data/user/0
mkdir /data/media 0770 media_rw media_rw
mkdir /data/media/obb 0770 media_rw media_rw
# Special-case /data/media/obb per b/64566063
mkdir /data/media 0770 media_rw media_rw encryption=None
mkdir /data/media/obb 0770 media_rw media_rw encryption=Attempt
mkdir /data/cache 0770 system cache
mkdir /data/cache 0770 system cache encryption=Require
mkdir /data/cache/recovery 0770 system cache
mkdir /data/cache/backup_stage 0700 system system
mkdir /data/cache/backup 0700 system system
mkdir /data/rollback 0700 system system
mkdir /data/rollback-observer 0700 system system
# Delete these if need be, per b/139193659
mkdir /data/rollback 0700 system system encryption=DeleteIfNecessary
mkdir /data/rollback-observer 0700 system system encryption=DeleteIfNecessary
# Wait for apexd to finish activating APEXes before starting more processes.
wait_for_prop apexd.status ready
@ -867,7 +869,7 @@ on property:sys.boot_completed=1
bootchart stop
# Setup per_boot directory so other .rc could start to use it on boot_completed
exec - system system -- /bin/rm -rf /data/per_boot
mkdir /data/per_boot 0700 system system
mkdir /data/per_boot 0700 system system encryption=Require key=per_boot_ref
# system server cannot write to /proc/sys files,
# and chown/chmod does not work for /proc/sys/ entries.

View file

@ -9,7 +9,7 @@ on post-fs-data
chown system system /sys/class/android_usb/android0/f_rndis/ethaddr
chmod 0660 /sys/class/android_usb/android0/f_rndis/ethaddr
mkdir /data/misc/adb 02750 system shell
mkdir /data/adb 0700 root root
mkdir /data/adb 0700 root root encryption=Require
# adbd is controlled via property triggers in init.<platform>.usb.rc
service adbd /system/bin/adbd --root_seclabel=u:r:su:s0