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:
parent
4645210097
commit
68258e8444
9 changed files with 290 additions and 197 deletions
|
@ -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".
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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 {};
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
136
init/util.cpp
136
init/util.cpp
|
@ -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 {
|
||||
|
|
12
init/util.h
12
init/util.h
|
@ -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);
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue