compos: Sign fs-verity digest of output files
compsvc now needs to be initialized with the signing key blob to finish
the whole compilation flow, otherwise it'll be an illegal state error.
"init-key" command is added to compos_key_cmd for that purpose.
Also, move some fs-verity related code into fsverity.rs.
Bug: 161471326
Test: ComposHostTestCases
Change-Id: I80db78ce11dc1f49e9ee36af47ad98f200aa4388
diff --git a/compos/src/compilation.rs b/compos/src/compilation.rs
index 24266e6..0199eb5 100644
--- a/compos/src/compilation.rs
+++ b/compos/src/compilation.rs
@@ -15,15 +15,13 @@
*/
use anyhow::{anyhow, bail, Context, Result};
-use libc::getxattr;
use log::error;
use minijail::{self, Minijail};
-use std::ffi::CString;
use std::fs::File;
-use std::io;
use std::os::unix::io::{AsRawFd, RawFd};
use std::path::Path;
+use crate::fsverity;
use authfs_aidl_interface::aidl::com::android::virt::fs::{
AuthFsConfig::AuthFsConfig, IAuthFs::IAuthFs, IAuthFsService::IAuthFsService,
InputFdAnnotation::InputFdAnnotation, OutputFdAnnotation::OutputFdAnnotation,
@@ -35,12 +33,13 @@
/// meaningless in the current process.
pub type PseudoRawFd = i32;
-const SHA256_HASH_SIZE: usize = 32;
-type Sha256Hash = [u8; SHA256_HASH_SIZE];
-
pub enum CompilerOutput {
/// Fs-verity digests of output files, if the compiler finishes successfully.
- Digests { oat: Sha256Hash, vdex: Sha256Hash, image: Sha256Hash },
+ Digests {
+ oat: fsverity::Sha256Digest,
+ vdex: fsverity::Sha256Digest,
+ image: fsverity::Sha256Digest,
+ },
/// Exit code returned by the compiler, if not 0.
ExitCode(i8),
}
@@ -82,9 +81,9 @@
match jail_result {
Ok(()) => Ok(CompilerOutput::Digests {
- oat: fsverity_measure(oat_file.as_raw_fd())?,
- vdex: fsverity_measure(vdex_file.as_raw_fd())?,
- image: fsverity_measure(image_file.as_raw_fd())?,
+ oat: fsverity::measure(oat_file.as_raw_fd())?,
+ vdex: fsverity::measure(vdex_file.as_raw_fd())?,
+ image: fsverity::measure(image_file.as_raw_fd())?,
}),
Err(minijail::Error::ReturnCode(exit_code)) => {
error!("dex2oat failed with exit code {}", exit_code);
@@ -186,22 +185,3 @@
let _pid = jail.run_remap(executable, preserve_fds.as_slice(), args)?;
Ok(jail)
}
-
-fn fsverity_measure(fd: RawFd) -> Result<Sha256Hash> {
- // TODO(b/196635431): Unfortunately, the FUSE API doesn't allow authfs to implement the standard
- // fs-verity ioctls. Until the kernel allows, use the alternative xattr that authfs provides.
- let path = CString::new(format!("/proc/self/fd/{}", fd).as_str()).unwrap();
- let name = CString::new("authfs.fsverity.digest").unwrap();
- let mut buf = [0u8; SHA256_HASH_SIZE];
- // SAFETY: getxattr should not write beyond the given buffer size.
- let size = unsafe {
- getxattr(path.as_ptr(), name.as_ptr(), buf.as_mut_ptr() as *mut libc::c_void, buf.len())
- };
- if size < 0 {
- bail!("Failed to getxattr: {}", io::Error::last_os_error());
- } else if size != SHA256_HASH_SIZE as isize {
- bail!("Unexpected hash size: {}", size);
- } else {
- Ok(buf)
- }
-}