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
This commit is contained in:
Jiyong Park 2021-12-21 13:53:42 +09:00
parent 173aca685a
commit 44e967db38
1 changed files with 26 additions and 1 deletions

View File

@ -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<Box<[u
fn get_bootconfig() -> Result<&'static Vec<u8>> {
static VAL: OnceCell<Vec<u8>> = OnceCell::new();
VAL.get_or_try_init(|| fs::read("/proc/bootconfig").context("Failed to read bootconfig"))
VAL.get_or_try_init(|| -> Result<Vec<u8>> {
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<VmPayloadConfig> {