Enable adb and adb root with debug level or debug policy
adb and adb root are enabled when debug level is full (--debug=full)
or debug policy allows so.
Debug policy is handled in init.rc instead of changing bootconfig
behavior. It allows the identity check to detect debug level changes
by bootconfig in the initrd regardless of debug policy.
Bug: 268270904, Bug: 26826551
Test: Manual test with custom debug policy
Change-Id: Ie6b0a6ae61e387d28873db91f1dcf08941b2fe61
diff --git a/microdroid/Android.bp b/microdroid/Android.bp
index bc4db6c..a2a4138 100644
--- a/microdroid/Android.bp
+++ b/microdroid/Android.bp
@@ -51,6 +51,7 @@
deps: [
"init_second_stage",
"microdroid_build_prop",
+ "microdroid_init_debug_policy",
"microdroid_init_rc",
"microdroid_ueventd_rc",
"microdroid_launcher",
diff --git a/microdroid/init.rc b/microdroid/init.rc
index 70c22d4..5187a12 100644
--- a/microdroid/init.rc
+++ b/microdroid/init.rc
@@ -21,13 +21,9 @@
write /linkerconfig/ld.config.txt \#
chmod 644 /linkerconfig/ld.config.txt
-# If VM is debuggable, send logs to outside ot the VM via the serial console.
-# If non-debuggable, logs are internally consumed at /dev/null
-on early-init && property:ro.boot.microdroid.debuggable=1
- setprop ro.log.file_logger.path /dev/hvc2
-
-on early-init && property:ro.boot.microdroid.debuggable=0
- setprop ro.log.file_logger.path /dev/null
+ # Applies debug policy to decide whether to enable adb, adb root, and logcat.
+ # We don't directly exec the binary to specify stdio_to_kmsg.
+ exec_start init_debug_policy
on init
mkdir /mnt/apk 0755 system system
@@ -47,8 +43,6 @@
# payloads are not designed to run with bootstrap bionic
setprop apex_config.done true
- setprop ro.debuggable ${ro.boot.microdroid.debuggable:-0}
-
on property:microdroid_manager.init_done=1
# Stop ueventd to save memory
stop ueventd
@@ -57,7 +51,7 @@
# Mount tracefs (with GID=AID_READTRACEFS)
mount tracefs tracefs /sys/kernel/tracing gid=3012
-on init && property:ro.boot.adb.enabled=1
+on property:init_debug_policy.adbd.enabled=1
start adbd
# Mount filesystems and start core system services.
@@ -179,3 +173,8 @@
group shell log readproc
seclabel u:r:shell:s0
setenv HOSTNAME console
+
+service init_debug_policy /system/bin/init_debug_policy
+ oneshot
+ disabled
+ stdio_to_kmsg
diff --git a/microdroid/init_debug_policy/Android.bp b/microdroid/init_debug_policy/Android.bp
new file mode 100644
index 0000000..b56ef79
--- /dev/null
+++ b/microdroid/init_debug_policy/Android.bp
@@ -0,0 +1,11 @@
+rust_binary {
+ name: "microdroid_init_debug_policy",
+ srcs: ["src/init_debug_policy.rs"],
+ stem: "init_debug_policy",
+ rustlibs: [
+ "librustutils",
+ ],
+ installable: false, // match with microdroid_init_rc.
+ bootstrap: true,
+ prefer_rlib: true,
+}
diff --git a/microdroid/init_debug_policy/src/init_debug_policy.rs b/microdroid/init_debug_policy/src/init_debug_policy.rs
new file mode 100644
index 0000000..6c80926
--- /dev/null
+++ b/microdroid/init_debug_policy/src/init_debug_policy.rs
@@ -0,0 +1,57 @@
+// Copyright 2023, The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+//! Applies debug policies when booting microdroid
+
+use rustutils::system_properties;
+use rustutils::system_properties::PropertyWatcherError;
+use std::fs::File;
+use std::io::Read;
+
+/// Get debug policy value in bool. It's true iff the value is explicitly set to <1>.
+fn get_debug_policy_bool(path: &'static str) -> Option<bool> {
+ let mut file = File::open(path).ok()?;
+ let mut log: [u8; 4] = Default::default();
+ file.read_exact(&mut log).ok()?;
+ // DT spec uses big endian although Android is always little endian.
+ Some(u32::from_be_bytes(log) == 1)
+}
+
+fn main() -> Result<(), PropertyWatcherError> {
+ // If VM is debuggable or debug policy says so, send logs to outside ot the VM via the serial console.
+ // Otherwise logs are internally consumed at /dev/null
+ let log_path = if system_properties::read_bool("ro.boot.microdroid.debuggable", false)?
+ || get_debug_policy_bool("/sys/firmware/devicetree/base/avf/guest/common/log")
+ .unwrap_or_default()
+ {
+ "/dev/hvc2"
+ } else {
+ "/dev/null"
+ };
+ system_properties::write("ro.log.file_logger.path", log_path)?;
+
+ let (adbd_enabled, debuggable) = if system_properties::read_bool("ro.boot.adb.enabled", false)?
+ || get_debug_policy_bool("/sys/firmware/devicetree/base/avf/guest/microdroid/adb")
+ .unwrap_or_default()
+ {
+ // debuggable is required for adb root and bypassing adb authorization.
+ ("1", "1")
+ } else {
+ ("0", "0")
+ };
+ system_properties::write("init_debug_policy.adbd.enabled", adbd_enabled)?;
+ system_properties::write("ro.debuggable", debuggable)?;
+
+ Ok(())
+}