init selinux.cpp: use a better way to detect if we run in Microdroid
We are now conditionally compiling init binaries & libinit for Microdroid (adding -DMICRODROID=1 cflag), so instead of checking for the presence of the /system/etc/selinux/microdroid_precompiled_sepolicy we can check if the code is compiled for Microdroid. In a follow-up changes we can split the sepolicy loading logic into 2 separate headers (one for Android and one for Microdroid) and include the necessary one depending on the target we compile for. Bug: 287206497 Test: atest MicrodroidTestApp Change-Id: Id9c837d03a96ff9564688d33955ec85094eee487
This commit is contained in:
parent
8790a71bc4
commit
a66adf45aa
5 changed files with 79 additions and 44 deletions
|
@ -214,8 +214,8 @@ cc_library_headers {
|
|||
visibility: [":__subpackages__"],
|
||||
}
|
||||
|
||||
cc_library_static {
|
||||
name: "libinit",
|
||||
cc_defaults {
|
||||
name: "libinit_defaults",
|
||||
recovery_available: true,
|
||||
defaults: [
|
||||
"init_defaults",
|
||||
|
@ -252,10 +252,17 @@ cc_library_static {
|
|||
],
|
||||
},
|
||||
},
|
||||
visibility: [
|
||||
"//system/apex/apexd",
|
||||
"//frameworks/native/cmds/installd",
|
||||
],
|
||||
}
|
||||
|
||||
cc_library_static {
|
||||
name: "libinit",
|
||||
defaults: ["libinit_defaults"],
|
||||
}
|
||||
|
||||
cc_library_static {
|
||||
name: "libinit.microdroid",
|
||||
defaults: ["libinit_defaults"],
|
||||
cflags: ["-DMICRODROID=1"],
|
||||
}
|
||||
|
||||
phony {
|
||||
|
@ -270,7 +277,6 @@ cc_defaults {
|
|||
recovery_available: true,
|
||||
stem: "init",
|
||||
defaults: ["init_defaults"],
|
||||
static_libs: ["libinit"],
|
||||
srcs: ["main.cpp"],
|
||||
symlinks: ["ueventd"],
|
||||
target: {
|
||||
|
@ -309,12 +315,14 @@ cc_defaults {
|
|||
cc_binary {
|
||||
name: "init_second_stage",
|
||||
defaults: ["init_second_stage_defaults"],
|
||||
static_libs: ["libinit"],
|
||||
}
|
||||
|
||||
cc_binary {
|
||||
name: "init_second_stage.microdroid",
|
||||
defaults: ["init_second_stage_defaults"],
|
||||
cflags: ["-DMICRODROID"],
|
||||
static_libs: ["libinit.microdroid"],
|
||||
cflags: ["-DMICRODROID=1"],
|
||||
installable: false,
|
||||
visibility: ["//packages/modules/Virtualization/microdroid"],
|
||||
}
|
||||
|
@ -460,7 +468,7 @@ cc_binary {
|
|||
cc_binary {
|
||||
name: "init_first_stage.microdroid",
|
||||
defaults: ["init_first_stage_defaults"],
|
||||
cflags: ["-DMICRODROID"],
|
||||
cflags: ["-DMICRODROID=1"],
|
||||
installable: false,
|
||||
}
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@ package {
|
|||
}
|
||||
|
||||
cc_defaults {
|
||||
name: "libinit_defaults",
|
||||
name: "libinit_fuzzer_defaults",
|
||||
static_libs: [
|
||||
"libc++fs",
|
||||
"liblmkd_utils",
|
||||
|
@ -53,7 +53,7 @@ cc_fuzz {
|
|||
],
|
||||
shared_libs: ["libhidlmetadata",],
|
||||
defaults: [
|
||||
"libinit_defaults",
|
||||
"libinit_fuzzer_defaults",
|
||||
],
|
||||
}
|
||||
|
||||
|
@ -62,7 +62,7 @@ cc_fuzz {
|
|||
srcs: [
|
||||
"init_property_fuzzer.cpp",
|
||||
],
|
||||
defaults: ["libinit_defaults"],
|
||||
defaults: ["libinit_fuzzer_defaults"],
|
||||
}
|
||||
|
||||
cc_fuzz {
|
||||
|
@ -71,6 +71,6 @@ cc_fuzz {
|
|||
"init_ueventHandler_fuzzer.cpp",
|
||||
],
|
||||
defaults: [
|
||||
"libinit_defaults",
|
||||
"libinit_fuzzer_defaults",
|
||||
],
|
||||
}
|
||||
|
|
|
@ -300,8 +300,6 @@ bool GetVendorMappingVersion(std::string* plat_vers) {
|
|||
}
|
||||
|
||||
constexpr const char plat_policy_cil_file[] = "/system/etc/selinux/plat_sepolicy.cil";
|
||||
constexpr const char kMicrodroidPrecompiledSepolicy[] =
|
||||
"/system/etc/selinux/microdroid_precompiled_sepolicy";
|
||||
|
||||
bool IsSplitPolicyDevice() {
|
||||
return access(plat_policy_cil_file, R_OK) != -1;
|
||||
|
@ -499,19 +497,14 @@ bool OpenSplitPolicy(PolicyFile* policy_file) {
|
|||
|
||||
bool OpenMonolithicPolicy(PolicyFile* policy_file) {
|
||||
static constexpr char kSepolicyFile[] = "/sepolicy";
|
||||
// In Microdroid the precompiled sepolicy is located on /system, since there is no vendor code.
|
||||
// TODO(b/287206497): refactor once we start conditionally compiling init for Microdroid.
|
||||
std::string monolithic_policy_file = access(kMicrodroidPrecompiledSepolicy, R_OK) == 0
|
||||
? kMicrodroidPrecompiledSepolicy
|
||||
: kSepolicyFile;
|
||||
|
||||
LOG(INFO) << "Opening SELinux policy from monolithic file " << monolithic_policy_file;
|
||||
policy_file->fd.reset(open(monolithic_policy_file.c_str(), O_RDONLY | O_CLOEXEC | O_NOFOLLOW));
|
||||
LOG(INFO) << "Opening SELinux policy from monolithic file " << kSepolicyFile;
|
||||
policy_file->fd.reset(open(kSepolicyFile, O_RDONLY | O_CLOEXEC | O_NOFOLLOW));
|
||||
if (policy_file->fd < 0) {
|
||||
PLOG(ERROR) << "Failed to open monolithic SELinux policy";
|
||||
return false;
|
||||
}
|
||||
policy_file->path = monolithic_policy_file;
|
||||
policy_file->path = kSepolicyFile;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -858,6 +851,10 @@ void SelinuxSetupKernelLogging() {
|
|||
}
|
||||
|
||||
int SelinuxGetVendorAndroidVersion() {
|
||||
if (IsMicrodroid()) {
|
||||
// As of now Microdroid doesn't have any vendor code.
|
||||
return __ANDROID_API_FUTURE__;
|
||||
}
|
||||
static int vendor_android_version = [] {
|
||||
if (!IsSplitPolicyDevice()) {
|
||||
// If this device does not split sepolicy files, it's not a Treble device and therefore,
|
||||
|
@ -961,6 +958,26 @@ static void LoadSelinuxPolicy(std::string& policy) {
|
|||
}
|
||||
}
|
||||
|
||||
// Encapsulates steps to load SELinux policy in Microdroid.
|
||||
// So far the process is very straightforward - just load the precompiled policy from /system.
|
||||
void LoadSelinuxPolicyMicrodroid() {
|
||||
constexpr const char kMicrodroidPrecompiledSepolicy[] =
|
||||
"/system/etc/selinux/microdroid_precompiled_sepolicy";
|
||||
|
||||
LOG(INFO) << "Opening SELinux policy from " << kMicrodroidPrecompiledSepolicy;
|
||||
unique_fd policy_fd(open(kMicrodroidPrecompiledSepolicy, O_RDONLY | O_CLOEXEC | O_NOFOLLOW));
|
||||
if (policy_fd < 0) {
|
||||
PLOG(FATAL) << "Failed to open " << kMicrodroidPrecompiledSepolicy;
|
||||
}
|
||||
|
||||
std::string policy;
|
||||
if (!android::base::ReadFdToString(policy_fd, &policy)) {
|
||||
PLOG(FATAL) << "Failed to read policy file: " << kMicrodroidPrecompiledSepolicy;
|
||||
}
|
||||
|
||||
LoadSelinuxPolicy(policy);
|
||||
}
|
||||
|
||||
// The SELinux setup process is carefully orchestrated around snapuserd. Policy
|
||||
// must be loaded off dynamic partitions, and during an OTA, those partitions
|
||||
// cannot be read without snapuserd. But, with kernel-privileged snapuserd
|
||||
|
@ -976,20 +993,9 @@ static void LoadSelinuxPolicy(std::string& policy) {
|
|||
// (5) Re-launch snapuserd and attach it to the dm-user devices from step (2).
|
||||
//
|
||||
// After this sequence, it is safe to enable enforcing mode and continue booting.
|
||||
int SetupSelinux(char** argv) {
|
||||
SetStdioToDevNull(argv);
|
||||
InitKernelLogging(argv);
|
||||
|
||||
if (REBOOT_BOOTLOADER_ON_PANIC) {
|
||||
InstallRebootSignalHandlers();
|
||||
}
|
||||
|
||||
boot_clock::time_point start_time = boot_clock::now();
|
||||
|
||||
void LoadSelinuxPolicyAndroid() {
|
||||
MountMissingSystemPartitions();
|
||||
|
||||
SelinuxSetupKernelLogging();
|
||||
|
||||
LOG(INFO) << "Opening SELinux policy";
|
||||
|
||||
PrepareApexSepolicy();
|
||||
|
@ -1001,9 +1007,8 @@ int SetupSelinux(char** argv) {
|
|||
|
||||
auto snapuserd_helper = SnapuserdSelinuxHelper::CreateIfNeeded();
|
||||
if (snapuserd_helper) {
|
||||
// Kill the old snapused to avoid audit messages. After this we cannot
|
||||
// read from /system (or other dynamic partitions) until we call
|
||||
// FinishTransition().
|
||||
// Kill the old snapused to avoid audit messages. After this we cannot read from /system
|
||||
// (or other dynamic partitions) until we call FinishTransition().
|
||||
snapuserd_helper->StartTransition();
|
||||
}
|
||||
|
||||
|
@ -1021,6 +1026,26 @@ int SetupSelinux(char** argv) {
|
|||
if (selinux_android_restorecon("/dev/selinux/", SELINUX_ANDROID_RESTORECON_RECURSE) == -1) {
|
||||
PLOG(FATAL) << "restorecon failed of /dev/selinux failed";
|
||||
}
|
||||
}
|
||||
|
||||
int SetupSelinux(char** argv) {
|
||||
SetStdioToDevNull(argv);
|
||||
InitKernelLogging(argv);
|
||||
|
||||
if (REBOOT_BOOTLOADER_ON_PANIC) {
|
||||
InstallRebootSignalHandlers();
|
||||
}
|
||||
|
||||
boot_clock::time_point start_time = boot_clock::now();
|
||||
|
||||
SelinuxSetupKernelLogging();
|
||||
|
||||
// TODO(b/287206497): refactor into different headers to only include what we need.
|
||||
if (IsMicrodroid()) {
|
||||
LoadSelinuxPolicyMicrodroid();
|
||||
} else {
|
||||
LoadSelinuxPolicyAndroid();
|
||||
}
|
||||
|
||||
SelinuxSetEnforcement();
|
||||
|
||||
|
|
|
@ -732,11 +732,6 @@ void SetDefaultMountNamespaceReady() {
|
|||
is_default_mount_namespace_ready = true;
|
||||
}
|
||||
|
||||
bool IsMicrodroid() {
|
||||
static bool is_microdroid = android::base::GetProperty("ro.hardware", "") == "microdroid";
|
||||
return is_microdroid;
|
||||
}
|
||||
|
||||
bool Has32BitAbi() {
|
||||
static bool has = !android::base::GetProperty("ro.product.cpu.abilist32", "").empty();
|
||||
return has;
|
||||
|
|
|
@ -105,7 +105,14 @@ bool IsRecoveryMode();
|
|||
bool IsDefaultMountNamespaceReady();
|
||||
void SetDefaultMountNamespaceReady();
|
||||
|
||||
bool IsMicrodroid();
|
||||
inline constexpr bool IsMicrodroid() {
|
||||
#ifdef MICRODROID
|
||||
return MICRODROID;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool Has32BitAbi();
|
||||
|
||||
std::string GetApexNameFromFileName(const std::string& path);
|
||||
|
|
Loading…
Reference in a new issue