From 44e967db386ec20e07a550e1b27d04ac4ffa694f Mon Sep 17 00:00:00 2001 From: Jiyong Park Date: Tue, 21 Dec 2021 13:53:42 +0900 Subject: [PATCH] Filter-out android.vbmeta.device when reading bootconfig android.vbmeta.device contains UUID of the vbmeta partition. The UUID may change everytime the VM is started because the UUID is recorded in the composite disk image which exists only while the VM is running. When the VM is stopped, the disk image is deleted (to save disk space) and re-created at the next time the VM is started. So far, even if a single bit is changed, we have refused to boot the VM. This is too aggressive given that the UUID can change every time. To address this issue, filter-out android.vbmeta.device config when reading bootconfig. This doesn't loosen the security because we still require that other configs (digest, debug mode, etc.) to be the same. Bug: 208442532 Test: run a VM multiple times with the same debug level -> boots run a VM multiple times with different debug levels -> not boots (as expected) Change-Id: I5af4bcdc1a18fcbc25e152b8e4af0dc8e9d8dc31 --- microdroid_manager/src/main.rs | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/microdroid_manager/src/main.rs b/microdroid_manager/src/main.rs index fccf0318..4420a49a 100644 --- a/microdroid_manager/src/main.rs +++ b/microdroid_manager/src/main.rs @@ -34,6 +34,7 @@ use payload::{get_apex_data_from_payload, load_metadata, to_metadata}; use rustutils::system_properties; use rustutils::system_properties::PropertyWatcher; use std::fs::{self, create_dir, File, OpenOptions}; +use std::io::BufRead; use std::os::unix::io::{FromRawFd, IntoRawFd}; use std::path::Path; use std::process::{Child, Command, Stdio}; @@ -435,7 +436,31 @@ fn get_public_key_from_apk(apk: &str, root_hash_trustful: bool) -> Result Result<&'static Vec> { static VAL: OnceCell> = OnceCell::new(); - VAL.get_or_try_init(|| fs::read("/proc/bootconfig").context("Failed to read bootconfig")) + VAL.get_or_try_init(|| -> Result> { + let f = File::open("/proc/bootconfig")?; + + // Filter-out androidboot.vbmeta.device which contains UUID of the vbmeta partition. That + // UUID could change everytime when the same VM is started because the composite disk image + // is ephemeral. A change in UUID is okay as long as other configs (e.g. + // androidboot.vbmeta.digest) remain same. + Ok(std::io::BufReader::new(f) + .lines() + // note: this try_fold is to early return when we fail to read a line from the file + .try_fold(Vec::new(), |mut lines, line| { + line.map(|s| { + lines.push(s); + lines + }) + })? + .into_iter() + .filter(|line| { + let tokens: Vec<&str> = line.splitn(2, '=').collect(); + // note: if `line` doesn't have =, tokens[0] is the entire line. + tokens[0].trim() != "androidboot.vbmeta.device" + }) + .flat_map(|line| (line + "\n").into_bytes()) + .collect()) + }) } fn load_config(path: &Path) -> Result {