Use fs-verity digests proto to build the directory
The proto contains path -> digest mapping. In this change, we start to
use the provided protobuf to build the directory. Digest is not yet
used.
Bug: 206869687
Test: atest AuthFsHostTest ComposHostTestCases MicrodroidTestCase
Change-Id: I0f03219c1243f20f9ec5099a451c6f588add9608
diff --git a/authfs/src/main.rs b/authfs/src/main.rs
index 18b7b51..0fa3db7 100644
--- a/authfs/src/main.rs
+++ b/authfs/src/main.rs
@@ -27,9 +27,11 @@
//! of the actual file name, the exposed file names through AuthFS are currently integer, e.g.
//! /mountpoint/42.
-use anyhow::{bail, Result};
+use anyhow::{anyhow, bail, Result};
use log::error;
+use protobuf::Message;
use std::convert::TryInto;
+use std::fs::File;
use std::path::{Path, PathBuf};
use structopt::StructOpt;
@@ -47,6 +49,7 @@
};
use fsstat::RemoteFsStatsReader;
use fsverity::{VerifiedFileEditor, VerifiedFileReader};
+use fsverity_digests_proto::fsverity_digests::FSVerityDigests;
use fusefs::{AuthFs, AuthFsEntry};
#[derive(StructOpt)]
@@ -93,10 +96,10 @@
/// remote host may be included in the mapping file, so the directory view may be partial. The
/// directory structure won't change throughout the filesystem lifetime.
///
- /// For example, `--remote-ro-dir 5:/path/to/mapping:/prefix/` tells the filesystem to
+ /// For example, `--remote-ro-dir 5:/path/to/mapping:prefix/` tells the filesystem to
/// construct a directory structure defined in the mapping file at $MOUNTPOINT/5, which may
- /// include a file like /5/system/framework/framework.jar. "/prefix/" tells the filesystem to
- /// strip the path (e.g. "/system/") from the mount point to match the expected location of the
+ /// include a file like /5/system/framework/framework.jar. "prefix/" tells the filesystem to
+ /// strip the path (e.g. "system/") from the mount point to match the expected location of the
/// remote FD (e.g. a directory FD of "/system" in the remote).
#[structopt(long, parse(try_from_str = parse_remote_new_ro_dir_option))]
remote_ro_dir: Vec<OptionRemoteRoDir>,
@@ -131,11 +134,9 @@
/// A mapping file that describes the expecting file/directory structure and integrity metadata
/// in the remote directory. The file contains serialized protobuf of
/// android.security.fsverity.FSVerityDigests.
- /// TODO(206869687): Really use the file when it's generated.
- #[allow(dead_code)]
mapping_file_path: PathBuf,
- prefix: PathBuf,
+ prefix: String,
}
fn parse_remote_ro_file_option(option: &str) -> Result<OptionRemoteRoFile> {
@@ -157,7 +158,7 @@
Ok(OptionRemoteRoDir {
remote_dir_fd: strs[0].parse::<i32>().unwrap(),
mapping_file_path: PathBuf::from(strs[1]),
- prefix: PathBuf::from(strs[2]),
+ prefix: String::from(strs[2]),
})
}
@@ -260,42 +261,25 @@
AuthFsEntry::ReadonlyDirectory { dir: InMemoryDir::new() },
)?;
- // TODO(206869687): Read actual path from config.mapping_file_path when it's generated.
- let paths = vec![
- Path::new("/system/framework/com.android.location.provider.jar"),
- Path::new("/system/framework/ethernet-service.jar"),
- Path::new("/system/framework/ext.jar"),
- Path::new("/system/framework/framework-graphics.jar"),
- Path::new("/system/framework/framework.jar"),
- Path::new("/system/framework/ims-common.jar"),
- Path::new("/system/framework/services.jar"),
- Path::new("/system/framework/services.jar.prof"),
- Path::new("/system/framework/telephony-common.jar"),
- Path::new("/system/framework/voip-common.jar"),
- Path::new("/system/etc/boot-image.prof"),
- Path::new("/system/etc/classpaths/bootclasspath.pb"),
- Path::new("/system/etc/classpaths/systemserverclasspath.pb"),
- Path::new("/system/etc/dirty-image-objects"),
- ];
-
- for path in &paths {
+ // Build the directory tree based on the mapping file.
+ let mut reader = File::open(&config.mapping_file_path)?;
+ let proto = FSVerityDigests::parse_from_reader(&mut reader)?;
+ for path_str in proto.digests.keys() {
let file_entry = {
+ let remote_path_str = path_str.strip_prefix(&config.prefix).ok_or_else(|| {
+ anyhow!("Expect path {} to match prefix {}", path_str, config.prefix)
+ })?;
// TODO(205883847): Not all files will be used. Open the remote file lazily.
- let related_path = path.strip_prefix(&config.prefix)?;
let remote_file = RemoteFileReader::new_by_path(
service.clone(),
config.remote_dir_fd,
- related_path,
+ Path::new(remote_path_str),
)?;
let file_size = service.getFileSize(remote_file.get_remote_fd())?.try_into()?;
// TODO(206869687): Switch to VerifiedReadonly
AuthFsEntry::UnverifiedReadonly { reader: remote_file, file_size }
};
- authfs.add_entry_at_ro_dir_by_path(
- dir_root_inode,
- path.strip_prefix("/")?,
- file_entry,
- )?;
+ authfs.add_entry_at_ro_dir_by_path(dir_root_inode, Path::new(path_str), file_entry)?;
}
}