Merge "Started on Virt Manager."
diff --git a/apex/Android.bp b/apex/Android.bp
index 7baf966..d6dda13 100644
--- a/apex/Android.bp
+++ b/apex/Android.bp
@@ -1,3 +1,7 @@
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
apex {
name: "com.android.virt",
@@ -9,7 +13,21 @@
key: "com.android.virt.key",
certificate: ":com.android.virt.certificate",
- min_sdk_version: "S",
+ // crosvm is enabled for only 64-bit targets on device
+ arch: {
+ arm64: {
+ binaries: [
+ "crosvm",
+ ],
+ },
+ x86_64: {
+ binaries: [
+ "crosvm",
+ ],
+ },
+ },
+ binaries: ["assemble_cvd"],
+ filesystems: ["microdroid"],
}
apex_key {
diff --git a/apex/product_packages.mk b/apex/product_packages.mk
new file mode 100644
index 0000000..ef99f0f
--- /dev/null
+++ b/apex/product_packages.mk
@@ -0,0 +1,33 @@
+#
+# Copyright (C) 2021 Google Inc.
+#
+# 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.
+#
+
+# TODO: Remove this once the APEX is included in base system.
+
+# To include the APEX in your build, insert this in your device.mk:
+# $(call inherit-product, packages/modules/Virtualization/apex/product_packages.mk)
+
+PRODUCT_PACKAGES += com.android.virt
+PRODUCT_ARTIFACT_PATH_REQUIREMENT_ALLOWED_LIST += \
+ system/apex/com.android.virt.apex \
+ system/bin/crosvm \
+ system/lib64/%.dylib.so \
+ system/lib64/libfdt.so \
+ system/lib64/libgfxstream_backend.so \
+ system/lib64/libcuttlefish_allocd_utils.so \
+ system/lib64/libcuttlefish_fs.so \
+ system/lib64/libcuttlefish_utils.so
+
+$(call inherit-product, external/crosvm/seccomp/crosvm_seccomp_policy_product_packages.mk)
diff --git a/authfs/Android.bp b/authfs/Android.bp
index 3c5849b..270be6e 100644
--- a/authfs/Android.bp
+++ b/authfs/Android.bp
@@ -1,19 +1,30 @@
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
rust_defaults {
name: "authfs_defaults",
crate_name: "authfs",
srcs: [
- "src/lib.rs",
+ "src/main.rs",
],
edition: "2018",
rustlibs: [
"libanyhow",
"libauthfs_crypto_bindgen",
+ "libcfg_if",
+ "libfuse_rust",
"liblibc",
+ "libstructopt",
"libthiserror",
],
- host_supported: true,
+ target: {
+ darwin: {
+ enabled: false,
+ },
+ },
shared_libs: ["libcrypto"],
- clippy_lints: "android",
+ defaults: ["crosvm_defaults"],
}
// TODO(b/172687320): remove once there is a canonical bindgen.
@@ -27,23 +38,15 @@
],
bindgen_flags: ["--size_t-is-usize"],
cflags: ["-D BORINGSSL_NO_CXX"],
- host_supported: true,
}
-rust_library {
- name: "libauthfs",
+rust_binary {
+ name: "authfs",
defaults: ["authfs_defaults"],
}
-rust_test_host {
- name: "authfs_host_test_src_lib",
- test_suites: ["general-tests"],
+rust_test {
+ name: "authfs_device_test_src_lib",
defaults: ["authfs_defaults"],
+ test_suites: ["device-tests"],
}
-
-// TODO(victorhsieh): Enable the test once "undefined symbol: _Unwind_Resume" is fixed, then add to
-// TEST_MAPPING.
-//rust_test {
-// name: "authfs_device_test_src_lib",
-// defaults: ["authfs_defaults"],
-//}
diff --git a/authfs/TEST_MAPPING b/authfs/TEST_MAPPING
new file mode 100644
index 0000000..d0c0b09
--- /dev/null
+++ b/authfs/TEST_MAPPING
@@ -0,0 +1,7 @@
+{
+ "presubmit": [
+ {
+ "name": "authfs_device_test_src_lib"
+ }
+ ]
+}
diff --git a/authfs/src/common.rs b/authfs/src/common.rs
new file mode 100644
index 0000000..2220ae7
--- /dev/null
+++ b/authfs/src/common.rs
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+pub const COMMON_PAGE_SIZE: u64 = 4096;
+
+pub fn divide_roundup(dividend: u64, divisor: u64) -> u64 {
+ (dividend + divisor - 1) / divisor
+}
diff --git a/authfs/src/fsverity.rs b/authfs/src/fsverity.rs
index c9070ba..29e15d4 100644
--- a/authfs/src/fsverity.rs
+++ b/authfs/src/fsverity.rs
@@ -19,6 +19,7 @@
use thiserror::Error;
use crate::auth::Authenticator;
+use crate::common::divide_roundup;
use crate::crypto::{CryptoError, Sha256Hasher};
use crate::reader::ReadOnlyDataByChunk;
@@ -43,10 +44,6 @@
type HashBuffer = [u8; Sha256Hasher::HASH_SIZE];
-fn divide_roundup(dividend: u64, divisor: u64) -> u64 {
- (dividend + divisor - 1) / divisor
-}
-
fn hash_with_padding(chunk: &[u8], pad_to: usize) -> Result<HashBuffer, CryptoError> {
let padding_size = pad_to - chunk.len();
Sha256Hasher::new()?.update(&chunk)?.update(&ZEROS[..padding_size])?.finalize()
@@ -91,11 +88,11 @@
/// offset of the child node's hash. It is up to the iterator user to use the node and hash,
/// e.g. for the actual verification.
#[allow(clippy::needless_collect)]
-fn fsverity_walk<'a, T: ReadOnlyDataByChunk>(
+fn fsverity_walk<T: ReadOnlyDataByChunk>(
chunk_index: u64,
file_size: u64,
- merkle_tree: &'a T,
-) -> Result<impl Iterator<Item = Result<([u8; 4096], usize), FsverityError>> + 'a, FsverityError> {
+ merkle_tree: &T,
+) -> Result<impl Iterator<Item = Result<([u8; 4096], usize), FsverityError>> + '_, FsverityError> {
let hashes_per_node = T::CHUNK_SIZE / Sha256Hasher::HASH_SIZE as u64;
let hash_pages = divide_roundup(file_size, hashes_per_node * T::CHUNK_SIZE);
debug_assert_eq!(hashes_per_node, 128u64);
@@ -168,7 +165,6 @@
}
impl<F: ReadOnlyDataByChunk, M: ReadOnlyDataByChunk> FsverityChunkedFileReader<F, M> {
- #[allow(dead_code)]
pub fn new<A: Authenticator>(
authenticator: &A,
chunked_file: F,
diff --git a/authfs/src/fusefs.rs b/authfs/src/fusefs.rs
new file mode 100644
index 0000000..484aad4
--- /dev/null
+++ b/authfs/src/fusefs.rs
@@ -0,0 +1,338 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+use anyhow::Result;
+use std::collections::BTreeMap;
+use std::convert::TryFrom;
+use std::ffi::CStr;
+use std::fs::OpenOptions;
+use std::io;
+use std::mem::MaybeUninit;
+use std::option::Option;
+use std::os::unix::io::AsRawFd;
+use std::path::Path;
+use std::time::Duration;
+
+use fuse::filesystem::{Context, DirEntry, DirectoryIterator, Entry, FileSystem, ZeroCopyWriter};
+use fuse::mount::MountOption;
+
+use crate::common::{divide_roundup, COMMON_PAGE_SIZE};
+use crate::fsverity::FsverityChunkedFileReader;
+use crate::reader::{ChunkedFileReader, ReadOnlyDataByChunk};
+
+// We're reading the backing file by chunk, so setting the block size to be the same.
+const BLOCK_SIZE: usize = COMMON_PAGE_SIZE as usize;
+
+const DEFAULT_METADATA_TIMEOUT: std::time::Duration = Duration::from_secs(5);
+
+pub type Inode = u64;
+type Handle = u64;
+
+// A debug only type where everything are stored as local files.
+type FileBackedFsverityChunkedFileReader =
+ FsverityChunkedFileReader<ChunkedFileReader, ChunkedFileReader>;
+
+pub enum FileConfig {
+ LocalVerifiedFile(FileBackedFsverityChunkedFileReader, u64),
+ LocalUnverifiedFile(ChunkedFileReader, u64),
+}
+
+struct AuthFs {
+ /// Store `FileConfig`s using the `Inode` number as the search index.
+ ///
+ /// For further optimization to minimize the search cost, since Inode is integer, we may
+ /// consider storing them in a Vec if we can guarantee that the numbers are small and
+ /// consecutive.
+ file_pool: BTreeMap<Inode, FileConfig>,
+
+ /// Maximum bytes in the write transaction to the FUSE device. This limits the maximum size to
+ /// a read request (including FUSE protocol overhead).
+ max_write: u32,
+}
+
+impl AuthFs {
+ pub fn new(file_pool: BTreeMap<Inode, FileConfig>, max_write: u32) -> AuthFs {
+ AuthFs { file_pool, max_write }
+ }
+
+ fn get_file_config(&self, inode: &Inode) -> io::Result<&FileConfig> {
+ self.file_pool.get(&inode).ok_or_else(|| io::Error::from_raw_os_error(libc::ENOENT))
+ }
+}
+
+fn check_access_mode(flags: u32, mode: libc::c_int) -> io::Result<()> {
+ if (flags & libc::O_ACCMODE as u32) == mode as u32 {
+ Ok(())
+ } else {
+ Err(io::Error::from_raw_os_error(libc::EACCES))
+ }
+}
+
+cfg_if::cfg_if! {
+ if #[cfg(all(target_arch = "aarch64", target_pointer_width = "64"))] {
+ fn blk_size() -> libc::c_int { BLOCK_SIZE as libc::c_int }
+ } else {
+ fn blk_size() -> libc::c_long { BLOCK_SIZE as libc::c_long }
+ }
+}
+
+fn create_stat(ino: libc::ino_t, file_size: u64) -> io::Result<libc::stat64> {
+ let mut st = unsafe { MaybeUninit::<libc::stat64>::zeroed().assume_init() };
+
+ st.st_ino = ino;
+ st.st_mode = libc::S_IFREG | libc::S_IRUSR | libc::S_IRGRP | libc::S_IROTH;
+ st.st_dev = 0;
+ st.st_nlink = 1;
+ st.st_uid = 0;
+ st.st_gid = 0;
+ st.st_rdev = 0;
+ st.st_size = libc::off64_t::try_from(file_size)
+ .map_err(|_| io::Error::from_raw_os_error(libc::EFBIG))?;
+ st.st_blksize = blk_size();
+ // Per man stat(2), st_blocks is "Number of 512B blocks allocated".
+ st.st_blocks = libc::c_longlong::try_from(divide_roundup(file_size, 512))
+ .map_err(|_| io::Error::from_raw_os_error(libc::EFBIG))?;
+ Ok(st)
+}
+
+/// An iterator that generates (offset, size) for a chunked read operation, where offset is the
+/// global file offset, and size is the amount of read from the offset.
+struct ChunkReadIter {
+ remaining: usize,
+ offset: u64,
+}
+
+impl ChunkReadIter {
+ pub fn new(remaining: usize, offset: u64) -> Self {
+ ChunkReadIter { remaining, offset }
+ }
+}
+
+impl Iterator for ChunkReadIter {
+ type Item = (u64, usize);
+
+ fn next(&mut self) -> Option<Self::Item> {
+ if self.remaining == 0 {
+ return None;
+ }
+ let chunk_data_size =
+ std::cmp::min(self.remaining, BLOCK_SIZE - (self.offset % BLOCK_SIZE as u64) as usize);
+ let retval = (self.offset, chunk_data_size);
+ self.offset += chunk_data_size as u64;
+ self.remaining = self.remaining.saturating_sub(chunk_data_size);
+ Some(retval)
+ }
+}
+
+fn offset_to_chunk_index(offset: u64) -> u64 {
+ offset / BLOCK_SIZE as u64
+}
+
+fn read_chunks<W: io::Write, T: ReadOnlyDataByChunk>(
+ mut w: W,
+ file: &T,
+ file_size: u64,
+ offset: u64,
+ size: u32,
+) -> io::Result<usize> {
+ let remaining = file_size.saturating_sub(offset);
+ let size_to_read = std::cmp::min(size as usize, remaining as usize);
+ let total = ChunkReadIter::new(size_to_read, offset).try_fold(
+ 0,
+ |total, (current_offset, planned_data_size)| {
+ // TODO(victorhsieh): There might be a non-trivial way to avoid this copy. For example,
+ // instead of accepting a buffer, the writer could expose the final destination buffer
+ // for the reader to write to. It might not be generally applicable though, e.g. with
+ // virtio transport, the buffer may not be continuous.
+ let mut buf = [0u8; BLOCK_SIZE];
+ let read_size = file.read_chunk(offset_to_chunk_index(current_offset), &mut buf)?;
+ if read_size < planned_data_size {
+ return Err(io::Error::from_raw_os_error(libc::ENODATA));
+ }
+
+ let begin = (current_offset % BLOCK_SIZE as u64) as usize;
+ let end = begin + planned_data_size;
+ let s = w.write(&buf[begin..end])?;
+ if s != planned_data_size {
+ return Err(io::Error::from_raw_os_error(libc::EIO));
+ }
+ Ok(total + s)
+ },
+ )?;
+
+ Ok(total)
+}
+
+// No need to support enumerating directory entries.
+struct EmptyDirectoryIterator {}
+
+impl DirectoryIterator for EmptyDirectoryIterator {
+ fn next(&mut self) -> Option<DirEntry> {
+ None
+ }
+}
+
+impl FileSystem for AuthFs {
+ type Inode = Inode;
+ type Handle = Handle;
+ type DirIter = EmptyDirectoryIterator;
+
+ fn max_buffer_size(&self) -> u32 {
+ self.max_write
+ }
+
+ fn lookup(&self, _ctx: Context, _parent: Inode, name: &CStr) -> io::Result<Entry> {
+ // Only accept file name that looks like an integrer. Files in the pool are simply exposed
+ // by their inode number. Also, there is currently no directory structure.
+ let num = name.to_str().map_err(|_| io::Error::from_raw_os_error(libc::EINVAL))?;
+ // Normally, `lookup` is required to increase a reference count for the inode (while
+ // `forget` will decrease it). It is not necessary here since the files are configured to
+ // be static.
+ let inode = num.parse::<Inode>().map_err(|_| io::Error::from_raw_os_error(libc::ENOENT))?;
+ let st = match self.get_file_config(&inode)? {
+ FileConfig::LocalVerifiedFile(_, file_size)
+ | FileConfig::LocalUnverifiedFile(_, file_size) => create_stat(inode, *file_size)?,
+ };
+ Ok(Entry {
+ inode,
+ generation: 0,
+ attr: st,
+ entry_timeout: DEFAULT_METADATA_TIMEOUT,
+ attr_timeout: DEFAULT_METADATA_TIMEOUT,
+ })
+ }
+
+ fn getattr(
+ &self,
+ _ctx: Context,
+ inode: Inode,
+ _handle: Option<Handle>,
+ ) -> io::Result<(libc::stat64, Duration)> {
+ Ok((
+ match self.get_file_config(&inode)? {
+ FileConfig::LocalVerifiedFile(_, file_size)
+ | FileConfig::LocalUnverifiedFile(_, file_size) => create_stat(inode, *file_size)?,
+ },
+ DEFAULT_METADATA_TIMEOUT,
+ ))
+ }
+
+ fn open(
+ &self,
+ _ctx: Context,
+ inode: Self::Inode,
+ flags: u32,
+ ) -> io::Result<(Option<Self::Handle>, fuse::sys::OpenOptions)> {
+ // Since file handle is not really used in later operations (which use Inode directly),
+ // return None as the handle..
+ match self.get_file_config(&inode)? {
+ FileConfig::LocalVerifiedFile(_, _) => {
+ check_access_mode(flags, libc::O_RDONLY)?;
+ // Once verified, and only if verified, the file content can be cached. This is not
+ // really needed for a local file, but is the behavior of RemoteVerifiedFile later.
+ Ok((None, fuse::sys::OpenOptions::KEEP_CACHE))
+ }
+ FileConfig::LocalUnverifiedFile(_, _) => {
+ check_access_mode(flags, libc::O_RDONLY)?;
+ // Do not cache the content. This type of file is supposed to be verified using
+ // dm-verity. The filesystem mount over dm-verity already is already cached, so use
+ // direct I/O here to avoid double cache.
+ Ok((None, fuse::sys::OpenOptions::DIRECT_IO))
+ }
+ }
+ }
+
+ fn read<W: io::Write + ZeroCopyWriter>(
+ &self,
+ _ctx: Context,
+ inode: Inode,
+ _handle: Handle,
+ w: W,
+ size: u32,
+ offset: u64,
+ _lock_owner: Option<u64>,
+ _flags: u32,
+ ) -> io::Result<usize> {
+ match self.get_file_config(&inode)? {
+ FileConfig::LocalVerifiedFile(file, file_size) => {
+ read_chunks(w, file, *file_size, offset, size)
+ }
+ FileConfig::LocalUnverifiedFile(file, file_size) => {
+ read_chunks(w, file, *file_size, offset, size)
+ }
+ }
+ }
+}
+
+/// Mount and start the FUSE instance. This requires CAP_SYS_ADMIN.
+pub fn loop_forever(
+ file_pool: BTreeMap<Inode, FileConfig>,
+ mountpoint: &Path,
+) -> Result<(), fuse::Error> {
+ let max_read: u32 = 65536;
+ let max_write: u32 = 65536;
+ let dev_fuse = OpenOptions::new()
+ .read(true)
+ .write(true)
+ .open("/dev/fuse")
+ .expect("Failed to open /dev/fuse");
+
+ fuse::mount(
+ mountpoint,
+ "authfs",
+ libc::MS_NOSUID | libc::MS_NODEV,
+ &[
+ MountOption::FD(dev_fuse.as_raw_fd()),
+ MountOption::RootMode(libc::S_IFDIR | libc::S_IXUSR | libc::S_IXGRP | libc::S_IXOTH),
+ MountOption::AllowOther,
+ MountOption::UserId(0),
+ MountOption::GroupId(0),
+ MountOption::MaxRead(max_read),
+ ],
+ )
+ .expect("Failed to mount fuse");
+
+ fuse::worker::start_message_loop(
+ dev_fuse,
+ max_write,
+ max_read,
+ AuthFs::new(file_pool, max_write),
+ )
+}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+
+ fn collect_chunk_read_iter(remaining: usize, offset: u64) -> Vec<(u64, usize)> {
+ ChunkReadIter::new(remaining, offset).collect::<Vec<_>>()
+ }
+
+ #[test]
+ fn test_chunk_read_iter() {
+ assert_eq!(collect_chunk_read_iter(4096, 0), [(0, 4096)]);
+ assert_eq!(collect_chunk_read_iter(8192, 0), [(0, 4096), (4096, 4096)]);
+ assert_eq!(collect_chunk_read_iter(8192, 4096), [(4096, 4096), (8192, 4096)]);
+
+ assert_eq!(
+ collect_chunk_read_iter(16384, 1),
+ [(1, 4095), (4096, 4096), (8192, 4096), (12288, 4096), (16384, 1)]
+ );
+
+ assert_eq!(collect_chunk_read_iter(0, 0), []);
+ assert_eq!(collect_chunk_read_iter(0, 100), []);
+ }
+}
diff --git a/authfs/src/lib.rs b/authfs/src/lib.rs
deleted file mode 100644
index 05070d6..0000000
--- a/authfs/src/lib.rs
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (C) 2020 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.
- */
-
-//! This crate provides a FUSE-based, non-generic filesystem that I/O is authenticated. This
-//! filesystem assumes the storage layer is not trusted, e.g. file is provided by an untrusted VM,
-//! and the content can't be simply trusted. The filesystem can use its public key to verify a
-//! (read-only) file against its associated fs-verity signature by a trusted party. With the Merkle
-//! tree, each read of file block can be verified individually.
-//!
-//! The implementation is not finished.
-
-mod auth;
-mod crypto;
-mod fsverity;
-mod reader;
diff --git a/authfs/src/main.rs b/authfs/src/main.rs
new file mode 100644
index 0000000..f0b5237
--- /dev/null
+++ b/authfs/src/main.rs
@@ -0,0 +1,155 @@
+/*
+ * Copyright (C) 2020 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.
+ */
+
+//! This crate implements AuthFS, a FUSE-based, non-generic filesystem where file access is
+//! authenticated. This filesystem assumes the underlying layer is not trusted, e.g. file may be
+//! provided by an untrusted host/VM, so that the content can't be simply trusted. However, with a
+//! public key from a trusted party, this filesystem can still verify a (read-only) file signed by
+//! the trusted party even if the host/VM as the blob provider is malicious. With the Merkle tree,
+//! each read of file block can be verified individually only when needed.
+//!
+//! AuthFS only serve files that are specifically configured. A file configuration may include the
+//! source (e.g. local file or remote file server), verification method (e.g. certificate for
+//! fs-verity verification, or no verification if expected to mount over dm-verity), and file ID.
+//! Regardless of the actual file name, the exposed file names through AuthFS are currently integer,
+//! e.g. /mountpoint/42.
+
+use anyhow::{bail, Result};
+use std::collections::BTreeMap;
+use std::fs::File;
+use std::io::Read;
+use std::path::PathBuf;
+use structopt::StructOpt;
+
+mod auth;
+mod common;
+mod crypto;
+mod fsverity;
+mod fusefs;
+mod reader;
+
+use auth::FakeAuthenticator;
+use fsverity::FsverityChunkedFileReader;
+use fusefs::{FileConfig, Inode};
+use reader::ChunkedFileReader;
+
+#[derive(StructOpt)]
+struct Options {
+ /// Mount point of AuthFS.
+ #[structopt(parse(from_os_str))]
+ mount_point: PathBuf,
+
+ /// Debug only. A readonly file to be protected by fs-verity. Can be multiple.
+ #[structopt(long, parse(try_from_str = parse_local_verified_file_option))]
+ local_verified_file: Vec<LocalVerifiedFileConfig>,
+
+ /// Debug only. An unverified read-only file. Can be multiple.
+ #[structopt(long, parse(try_from_str = parse_local_unverified_file_option))]
+ local_unverified_file: Vec<LocalUnverifiedFileConfig>,
+}
+
+struct LocalVerifiedFileConfig {
+ ino: Inode,
+ file_path: PathBuf,
+ merkle_tree_dump_path: PathBuf,
+ signature_path: PathBuf,
+}
+
+struct LocalUnverifiedFileConfig {
+ ino: Inode,
+ file_path: PathBuf,
+}
+
+fn parse_local_verified_file_option(option: &str) -> Result<LocalVerifiedFileConfig> {
+ let strs: Vec<&str> = option.split(':').collect();
+ if strs.len() != 4 {
+ bail!("Invalid option: {}", option);
+ }
+ Ok(LocalVerifiedFileConfig {
+ ino: strs[0].parse::<Inode>().unwrap(),
+ file_path: PathBuf::from(strs[1]),
+ merkle_tree_dump_path: PathBuf::from(strs[2]),
+ signature_path: PathBuf::from(strs[3]),
+ })
+}
+
+fn parse_local_unverified_file_option(option: &str) -> Result<LocalUnverifiedFileConfig> {
+ let strs: Vec<&str> = option.split(':').collect();
+ if strs.len() != 2 {
+ bail!("Invalid option: {}", option);
+ }
+ Ok(LocalUnverifiedFileConfig {
+ ino: strs[0].parse::<Inode>().unwrap(),
+ file_path: PathBuf::from(strs[1]),
+ })
+}
+
+fn new_config_local_verified_file(
+ protected_file: &PathBuf,
+ merkle_tree_dump: &PathBuf,
+ signature: &PathBuf,
+) -> Result<FileConfig> {
+ let file = File::open(&protected_file)?;
+ let file_size = file.metadata()?.len();
+ let file_reader = ChunkedFileReader::new(file)?;
+ let merkle_tree_reader = ChunkedFileReader::new(File::open(merkle_tree_dump)?)?;
+ let authenticator = FakeAuthenticator::always_succeed();
+ let mut sig = Vec::new();
+ let _ = File::open(signature)?.read_to_end(&mut sig)?;
+ let file_reader = FsverityChunkedFileReader::new(
+ &authenticator,
+ file_reader,
+ file_size,
+ sig,
+ merkle_tree_reader,
+ )?;
+ Ok(FileConfig::LocalVerifiedFile(file_reader, file_size))
+}
+
+fn new_config_local_unverified_file(file_path: &PathBuf) -> Result<FileConfig> {
+ let file = File::open(file_path)?;
+ let file_size = file.metadata()?.len();
+ let file_reader = ChunkedFileReader::new(file)?;
+ Ok(FileConfig::LocalUnverifiedFile(file_reader, file_size))
+}
+
+fn prepare_file_pool(args: &Options) -> Result<BTreeMap<Inode, FileConfig>> {
+ let mut file_pool = BTreeMap::new();
+
+ for config in &args.local_verified_file {
+ file_pool.insert(
+ config.ino,
+ new_config_local_verified_file(
+ &config.file_path,
+ &config.merkle_tree_dump_path,
+ &config.signature_path,
+ )?,
+ );
+ }
+
+ for config in &args.local_unverified_file {
+ file_pool.insert(config.ino, new_config_local_unverified_file(&config.file_path)?);
+ }
+
+ Ok(file_pool)
+}
+
+fn main() -> Result<()> {
+ let args = Options::from_args();
+ let file_pool = prepare_file_pool(&args)?;
+ fusefs::loop_forever(file_pool, &args.mount_point)?;
+ Ok(())
+}
diff --git a/authfs/src/reader.rs b/authfs/src/reader.rs
index 135a793..2d1b617 100644
--- a/authfs/src/reader.rs
+++ b/authfs/src/reader.rs
@@ -19,13 +19,14 @@
use std::fs::File;
use std::io::Result;
use std::os::unix::fs::FileExt;
-use std::path::Path;
+
+use crate::common::COMMON_PAGE_SIZE;
/// A trait for reading data by chunks. The data is assumed readonly and has fixed length. Chunks
/// can be read by specifying the chunk index. Only the last chunk may have incomplete chunk size.
pub trait ReadOnlyDataByChunk {
/// Default chunk size.
- const CHUNK_SIZE: u64 = 4096;
+ const CHUNK_SIZE: u64 = COMMON_PAGE_SIZE;
/// Read the `chunk_index`-th chunk to `buf`. Each slice/chunk has size `CHUNK_SIZE` except for
/// the last one, which can be an incomplete chunk. `buf` is currently required to be large
@@ -49,9 +50,7 @@
impl ChunkedFileReader {
/// Creates a `ChunkedFileReader` to read from for the specified `path`.
- #[allow(dead_code)]
- pub fn new<P: AsRef<Path>>(path: P) -> Result<ChunkedFileReader> {
- let file = File::open(path)?;
+ pub fn new(file: File) -> Result<ChunkedFileReader> {
let size = file.metadata()?.len();
Ok(ChunkedFileReader { file, size })
}
diff --git a/authfs/tools/test.sh b/authfs/tools/test.sh
new file mode 100755
index 0000000..9ed3a99
--- /dev/null
+++ b/authfs/tools/test.sh
@@ -0,0 +1,42 @@
+#!/bin/bash
+
+# Run with -u to enter new namespace.
+if [[ $1 == "-u" ]]; then
+ exec unshare -m -U -r $0
+fi
+
+trap "umount /tmp/mnt" EXIT;
+mkdir -p /tmp/mnt
+
+echo "Mounting authfs in background ..."
+strace -o authfs.strace target/debug/authfs \
+ /tmp/mnt \
+ --local-verified-file 2:testdata/input.4m:testdata/input.4m.merkle_dump:testdata/input.4m.fsv_sig \
+ --local-verified-file 3:testdata/input.4k1:testdata/input.4k1.merkle_dump:testdata/input.4k1.fsv_sig \
+ --local-verified-file 4:testdata/input.4k:testdata/input.4k.merkle_dump:testdata/input.4k.fsv_sig \
+ --local-unverified-file 5:testdata/input.4k \
+ &
+sleep 0.1
+
+echo "Accessing files in authfs ..."
+echo
+md5sum /tmp/mnt/2 testdata/input.4m
+echo
+md5sum /tmp/mnt/3 testdata/input.4k1
+echo
+md5sum /tmp/mnt/4 /tmp/mnt/5 testdata/input.4k
+echo
+dd if=/tmp/mnt/2 bs=1000 skip=100 count=50 status=none |md5sum
+dd if=testdata/input.4m bs=1000 skip=100 count=50 status=none |md5sum
+echo
+tac /tmp/mnt/4 |md5sum
+tac /tmp/mnt/5 |md5sum
+tac testdata/input.4k |md5sum
+echo
+test -f /tmp/mnt/2 || echo 'FAIL: an expected file is missing'
+test -f /tmp/mnt/0 && echo 'FAIL: unexpected file presents'
+test -f /tmp/mnt/1 && echo 'FAIL: unexpected file presents, 1 is root dir'
+test -f /tmp/mnt/100 && echo 'FAIL: unexpected file presents'
+test -f /tmp/mnt/foo && echo 'FAIL: unexpected file presents'
+test -f /tmp/mnt/dir/3 && echo 'FAIL: unexpected file presents'
+echo "Done!"
diff --git a/microdroid/Android.bp b/microdroid/Android.bp
new file mode 100644
index 0000000..f163d77
--- /dev/null
+++ b/microdroid/Android.bp
@@ -0,0 +1,36 @@
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+android_filesystem {
+ name: "microdroid",
+ use_avb: true,
+ avb_private_key: "microdroid.pem",
+ avb_algorithm: "SHA256_RSA4096",
+ deps: [
+ "init_second_stage",
+ ],
+ file_contexts: "microdroid_file_contexts",
+}
+
+bootimg {
+ name: "microdroid_vendor_boot-5.10",
+ ramdisk_module: "microdroid_ramdisk-5.10",
+ dtb_prebuilt: "dummy_dtb.img",
+ header_version: "3",
+ vendor_boot: true,
+ partition_name: "vendor_boot",
+}
+
+android_filesystem {
+ name: "microdroid_ramdisk-5.10",
+ arch: {
+ arm64: {
+ deps: ["virt_device_prebuilts_kernel_modules-5.10-arm64"],
+ },
+ x86_64: {
+ deps: ["virt_device_prebuilts_kernel_modules-5.10-x86_64"],
+ },
+ },
+ type: "compressed_cpio",
+}
diff --git a/microdroid/dummy_dtb.img b/microdroid/dummy_dtb.img
new file mode 100644
index 0000000..9d6cec7
--- /dev/null
+++ b/microdroid/dummy_dtb.img
@@ -0,0 +1 @@
+workaround
diff --git a/microdroid/microdroid.pem b/microdroid/microdroid.pem
new file mode 100644
index 0000000..2c9de45
--- /dev/null
+++ b/microdroid/microdroid.pem
@@ -0,0 +1,51 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIJKAIBAAKCAgEAwOn8PTeXaSbNtTx0iJspX7ZJn1dUWHeDtq/r6HPTCEnFuYqV
+c4foSjbF3nIR5T5ZxLeAcTYUl2A/mieUYKG7DkySf5LGlAgWOn4/UXSl14fvESBK
+XA51w9Stg3GyWycYYVkz52mDWfkfoic2UVQJXpsTTcAFDR+u8e5oDxscgLbU7/g2
+mbOv7E4B5n6ItscmjxzRh1IvFVRlPzzyDYQ8UF3JDk0Ndoz7Pze5hF72zbkH6Dmh
+zS91xZFuIJNPjEEjr4Nli9xADhEdsRPeJoFQa+XafGabR2Z2jbVk1UqkD0yxvDhw
+jQaSQ2P6W/flzJnQgRr21FHONU9B6sh+p2ulK3Huda7JIdCExA2SsP+2PVE1Kw9G
+s+85o1/8rfa576qwSLR++ztvZwg3DF/4UQME2oqGLM9TLyj8bdN3Co4XSwsJ7pru
+1WgyQ6S8qLrGld4oxxTbQYoVIhEjUjiOHSKggflZ76Mscnh5hv6ZnuhpbV0b0zSB
+95hP/fbc7VP3ru6ArHA3HF84MQ6i60YPrB5ZpB39wbex1AynbGG0bHw9kgo7L4bF
+rE6p7T6cVazWd0LcWE+WgBHXU2dcVtMPmxUTyzhoeTSVv6eDqagTCe0q3IBZ9h4c
+5q7O6Ipbu/3ckEeRlzBFp7ymjGosqZL0siYtNSKo+FJxvEtbcEiz8xKU6ksCAwEA
+AQKCAgABk+hUN9gtK/wSt2PcmihEeCEyBGzULGYPYHD1fb0EHFZZpiCCyWHE+Z20
+rAopbdEeIsISKvcQJeFfSWOVRr1Y6JdqI7EsFMTZxZ6O8/1HPf1ejn0NM7ES4PJq
+WMu0oyU35preEabZXYg8s0VmdOF+vJXz1NY1vUSZBfIj7XzWMKidLdKEf0u5CwpI
+8E/97rMKCJpOGQX5jq8lTUJNif9USPAUBd1OUujbI4GI653pINJHu/Du1KyJ6R6V
+dZ747q90CAcUlcCQXON5R0hR2EzoFQEsc0ph0xy1G/6vH+UnmuD5QRzqils34eFy
+Txy6B6gE5kuOgPzGwtcvLGScyeyX4rjA1RS+Zst8PQG35D2WSLENbITDZ2u2n146
+C/TWWd6F/qE8cSCI8/ZQ5iEarw8Hp3sVe7KRqwG0n2ESlW/px6E9DmzbjgW/BLwB
+diBLmHVmOT5BZPqbjNiwsX/aLmf7cjtnttFuadf2roaa6jlyQzsqRyVzJKH2H9iD
+DFeakMAjngVW0XnWrpgehoG5JfWDbXWcg8Kt5ZlegSOs1KGBAj69RkotJWjQ2rlP
+TijMuHgXVUIvqQp5BIc8UnVqX3kzljLd2eVM0K6ZcPnh+yBhk/Jd88whxkONgbs4
+g8EQvov4c8UL1Sx2ZTDDCN0WK0dHG1IhtB/E014yFIq/qqQMQQKCAQEA8c6tw7o+
+36Uh1uB5oEw6zSsxY7x13cW9tis9slD4/bXiXJwTOjs1/+S+wrmJ4UoOarygFgh0
+xWc1YGs20UWBkO4T9jaZJBqESH96RvQn7ubBEHYECClPhRuwbWWc+UzHjgusmuYl
+xPtY9MgtI5AF6O2MEqzCWbLZzFhhe/V6FKKcyV3aq6vOEjCeTz0/ntfcfS08T/5l
+kayny1nlVju3eig5WK30+X66rN0+eYS1PqLInlzSpFGWMJA6s+uI+1ze506QWKFI
+vNPf4Wtm8VFksRSbrYBriKg63UsgOGfaq5zmgJ5Yst8tIheKLJE5meLjGcea8Dhe
+gz+Jtj+Es9WdVQKCAQEAzDymkIOrwh8j45zFuH+6vataWkGusloV3P6dE0V5NDPH
+Oa/EfOqZ3qQKiS8bHRcdEwRQK+TSeOWi6phDQVu2lzwBA1PySxz7T1T38RKP9myu
+yPFah6bLKntvE36fj3U7RaU2gf8GXGMuwoRWoGDQNHQ+YusKOFreht7dlclqLKKp
+Xct7lKrg3nOtJI3P/jxXZwE/+UenqS5M8QOd7X0/77d9VJBYAhUZ9A5cOuk327e+
+zxEeg23UndcqmJRj0zsxYR+d/NaDV9yf8usAHRv/S3nwVN6YkmmnVNY46ukCNlxV
+G9VZcM1PNWFu3MdGs7f8u973DXYMC3Et3JD8/XNpHwKCAQEAoN8g6dOx2raRAdUL
+9eJhSHhQ/oq2W9ofsd+ox0ZpsNleBMDtZdNYxKsZYpFvssvDNa3ST3ZGwcI9V61c
+pfO5FIPgEfEXB1cA5P6yihwLqTwp+9qYKhnZxrO6N73fplg3d0A7ED7Hp/qUnx3C
+MiOyWtoXU6FOF8EOd43hJUgWdT4OU0W2onnFuoJQAGW+Ot5f2YPL2WhliHo2k+p1
+0l4eXg3+wQnSrl5qsXDsDIqGzmocUIduuFVzN1HtTCAKXTjXL0osbFq4+q93BhCf
+RzMga1NLky2Z3SwXJXzCreQiLgRPsggm+LHT5BeHHMltafzxnAgZA3JtJqKR6wbt
+MXuPlQKCAQBRaWvL93Cj9N3NgVSfcurxaDif+ca1eYt1iFj8sZja4jjsGdBtKucj
+BKjeflSEiA4i4nlCxffQEVmbwg4tI23pYxXUScYvguH6gZhEFG4mgLQ7jVnU8PvT
+d1iToMnh2Y1C+dR8hTf34+Fj0HTngS/9eMjVjXOJe09w263gY2VbXYu9w7sDTApP
+IjVGePEMGumMOcdSiumeWsJ44EQ3wtGVsMLYzqEGU3sA+ihxoz2M6/W3fM94/HLg
+aECmiaAxN0s7t+q2Opwojd2Ea4CkGeDuKTFP41tWIZ9+BdaybSdgm/WhHq6EdJK6
+aJhUkWrxgMnR6dL5HrE2bmslnPX74eFpAoIBAE4epxTb9SstOxhwFA1Vvrz5G64k
+n61OgXj49QPpBcBOGXVH1l8L6YQJO+bCVESiACn2Q/lJ8mp6lRI2KtsemUfsa5X7
+XV1qldtTFobMmB4JZDTEM882TWainK2+yhGfEGWrdeCWDBSWqQj/VLpAUqQqdJFU
++GRvPQV+DSk4Az7zGpyrtjpiZYbRjWHBT2FAwSRS/iqEHjKrvrCqlaq16Un0JJFb
+0ztbCC2tDaVlwpojPnPE2sgojYeGQ0ghB1os9K4RFaoW9l+Pfye5vJ9G0/wmjVhY
+HQaN/WJp8k79mXacCQAD51xtWnJePGd4D5WbA855jo0Dov/mOtwf0Ahbl6w=
+-----END RSA PRIVATE KEY-----
diff --git a/microdroid/microdroid_file_contexts b/microdroid/microdroid_file_contexts
new file mode 100644
index 0000000..6d36e7c
--- /dev/null
+++ b/microdroid/microdroid_file_contexts
@@ -0,0 +1,789 @@
+# This is a copy of system/sepolicy/private/file_contexts to build microdroid.img.
+# TODO(inseob): Remove unnecessary entries after experiment
+
+###########################################
+# Root
+/ u:object_r:rootfs:s0
+
+# Data files
+/adb_keys u:object_r:adb_keys_file:s0
+/build\.prop u:object_r:rootfs:s0
+/default\.prop u:object_r:rootfs:s0
+/fstab\..* u:object_r:rootfs:s0
+/init\..* u:object_r:rootfs:s0
+/res(/.*)? u:object_r:rootfs:s0
+/selinux_version u:object_r:rootfs:s0
+/ueventd\..* u:object_r:rootfs:s0
+/verity_key u:object_r:rootfs:s0
+
+# Executables
+/init u:object_r:init_exec:s0
+/sbin(/.*)? u:object_r:rootfs:s0
+
+# For kernel modules
+/lib(/.*)? u:object_r:rootfs:s0
+
+# Empty directories
+/lost\+found u:object_r:rootfs:s0
+/acct u:object_r:cgroup:s0
+/config u:object_r:rootfs:s0
+/data_mirror u:object_r:mirror_data_file:s0
+/debug_ramdisk u:object_r:tmpfs:s0
+/mnt u:object_r:tmpfs:s0
+/postinstall u:object_r:postinstall_mnt_dir:s0
+/postinstall/apex u:object_r:postinstall_apex_mnt_dir:s0
+/proc u:object_r:rootfs:s0
+/second_stage_resources u:object_r:tmpfs:s0
+/sys u:object_r:sysfs:s0
+/apex u:object_r:apex_mnt_dir:s0
+
+/apex/(\.(bootstrap|default)-)?apex-info-list.xml u:object_r:apex_info_file:s0
+
+# Symlinks
+/bin u:object_r:rootfs:s0
+/bugreports u:object_r:rootfs:s0
+/charger u:object_r:rootfs:s0
+/d u:object_r:rootfs:s0
+/etc u:object_r:rootfs:s0
+/sdcard u:object_r:rootfs:s0
+
+# SELinux policy files
+/vendor_file_contexts u:object_r:file_contexts_file:s0
+/nonplat_file_contexts u:object_r:file_contexts_file:s0
+/plat_file_contexts u:object_r:file_contexts_file:s0
+/product_file_contexts u:object_r:file_contexts_file:s0
+/mapping_sepolicy\.cil u:object_r:sepolicy_file:s0
+/nonplat_sepolicy\.cil u:object_r:sepolicy_file:s0
+/plat_sepolicy\.cil u:object_r:sepolicy_file:s0
+/plat_property_contexts u:object_r:property_contexts_file:s0
+/product_property_contexts u:object_r:property_contexts_file:s0
+/nonplat_property_contexts u:object_r:property_contexts_file:s0
+/vendor_property_contexts u:object_r:property_contexts_file:s0
+/seapp_contexts u:object_r:seapp_contexts_file:s0
+/nonplat_seapp_contexts u:object_r:seapp_contexts_file:s0
+/vendor_seapp_contexts u:object_r:seapp_contexts_file:s0
+/plat_seapp_contexts u:object_r:seapp_contexts_file:s0
+/sepolicy u:object_r:sepolicy_file:s0
+/plat_service_contexts u:object_r:service_contexts_file:s0
+/plat_hwservice_contexts u:object_r:hwservice_contexts_file:s0
+/plat_keystore2_key_contexts u:object_r:keystore2_key_contexts_file:s0
+/nonplat_service_contexts u:object_r:nonplat_service_contexts_file:s0
+# Use nonplat_service_contexts_file to allow servicemanager to read it
+# on non full-treble devices.
+/vendor_service_contexts u:object_r:nonplat_service_contexts_file:s0
+/nonplat_hwservice_contexts u:object_r:hwservice_contexts_file:s0
+/vendor_hwservice_contexts u:object_r:hwservice_contexts_file:s0
+/vndservice_contexts u:object_r:vndservice_contexts_file:s0
+
+##########################
+# Devices
+#
+/dev(/.*)? u:object_r:device:s0
+/dev/adf[0-9]* u:object_r:graphics_device:s0
+/dev/adf-interface[0-9]*\.[0-9]* u:object_r:graphics_device:s0
+/dev/adf-overlay-engine[0-9]*\.[0-9]* u:object_r:graphics_device:s0
+/dev/ashmem u:object_r:ashmem_device:s0
+/dev/ashmem(.*)? u:object_r:ashmem_libcutils_device:s0
+/dev/audio.* u:object_r:audio_device:s0
+/dev/binder u:object_r:binder_device:s0
+/dev/block(/.*)? u:object_r:block_device:s0
+/dev/block/dm-[0-9]+ u:object_r:dm_device:s0
+/dev/block/loop[0-9]* u:object_r:loop_device:s0
+/dev/block/vold/.+ u:object_r:vold_device:s0
+/dev/block/ram[0-9]* u:object_r:ram_device:s0
+/dev/block/zram[0-9]* u:object_r:ram_device:s0
+/dev/boringssl/selftest(/.*)? u:object_r:boringssl_self_test_marker:s0
+/dev/bus/usb(.*)? u:object_r:usb_device:s0
+/dev/console u:object_r:console_device:s0
+/dev/cpu_variant:.* u:object_r:dev_cpu_variant:s0
+/dev/dma_heap(/.*)? u:object_r:dmabuf_heap_device:s0
+/dev/dma_heap/system u:object_r:dmabuf_system_heap_device:s0
+/dev/dma_heap/system-uncached u:object_r:dmabuf_system_heap_device:s0
+/dev/dma_heap/system-secure u:object_r:dmabuf_system_secure_heap_device:s0
+/dev/dm-user(/.*)? u:object_r:dm_user_device:s0
+/dev/device-mapper u:object_r:dm_device:s0
+/dev/eac u:object_r:audio_device:s0
+/dev/event-log-tags u:object_r:runtime_event_log_tags_file:s0
+/dev/cgroup_info(/.*)? u:object_r:cgroup_rc_file:s0
+/dev/fscklogs(/.*)? u:object_r:fscklogs:s0
+/dev/fuse u:object_r:fuse_device:s0
+/dev/gnss[0-9]+ u:object_r:gnss_device:s0
+/dev/graphics(/.*)? u:object_r:graphics_device:s0
+/dev/hw_random u:object_r:hw_random_device:s0
+/dev/hwbinder u:object_r:hwbinder_device:s0
+/dev/input(/.*)? u:object_r:input_device:s0
+/dev/iio:device[0-9]+ u:object_r:iio_device:s0
+/dev/ion u:object_r:ion_device:s0
+/dev/keychord u:object_r:keychord_device:s0
+/dev/loop-control u:object_r:loop_control_device:s0
+/dev/modem.* u:object_r:radio_device:s0
+/dev/mtp_usb u:object_r:mtp_device:s0
+/dev/pmsg0 u:object_r:pmsg_device:s0
+/dev/pn544 u:object_r:nfc_device:s0
+/dev/port u:object_r:port_device:s0
+/dev/ppp u:object_r:ppp_device:s0
+/dev/ptmx u:object_r:ptmx_device:s0
+/dev/pvrsrvkm u:object_r:gpu_device:s0
+/dev/kmsg u:object_r:kmsg_device:s0
+/dev/kmsg_debug u:object_r:kmsg_debug_device:s0
+/dev/null u:object_r:null_device:s0
+/dev/nvhdcp1 u:object_r:video_device:s0
+/dev/random u:object_r:random_device:s0
+/dev/rpmsg-omx[0-9] u:object_r:rpmsg_device:s0
+/dev/rproc_user u:object_r:rpmsg_device:s0
+/dev/rtc[0-9] u:object_r:rtc_device:s0
+/dev/snd(/.*)? u:object_r:audio_device:s0
+/dev/socket(/.*)? u:object_r:socket_device:s0
+/dev/socket/adbd u:object_r:adbd_socket:s0
+/dev/socket/dnsproxyd u:object_r:dnsproxyd_socket:s0
+/dev/socket/dumpstate u:object_r:dumpstate_socket:s0
+/dev/socket/fwmarkd u:object_r:fwmarkd_socket:s0
+/dev/socket/lmkd u:object_r:lmkd_socket:s0
+/dev/socket/logd u:object_r:logd_socket:s0
+/dev/socket/logdr u:object_r:logdr_socket:s0
+/dev/socket/logdw u:object_r:logdw_socket:s0
+/dev/socket/statsdw u:object_r:statsdw_socket:s0
+/dev/socket/mdns u:object_r:mdns_socket:s0
+/dev/socket/mdnsd u:object_r:mdnsd_socket:s0
+/dev/socket/mtpd u:object_r:mtpd_socket:s0
+/dev/socket/pdx/system/buffer_hub u:object_r:pdx_bufferhub_dir:s0
+/dev/socket/pdx/system/buffer_hub/client u:object_r:pdx_bufferhub_client_endpoint_socket:s0
+/dev/socket/pdx/system/performance u:object_r:pdx_performance_dir:s0
+/dev/socket/pdx/system/performance/client u:object_r:pdx_performance_client_endpoint_socket:s0
+/dev/socket/pdx/system/vr/display u:object_r:pdx_display_dir:s0
+/dev/socket/pdx/system/vr/display/client u:object_r:pdx_display_client_endpoint_socket:s0
+/dev/socket/pdx/system/vr/display/manager u:object_r:pdx_display_manager_endpoint_socket:s0
+/dev/socket/pdx/system/vr/display/screenshot u:object_r:pdx_display_screenshot_endpoint_socket:s0
+/dev/socket/pdx/system/vr/display/vsync u:object_r:pdx_display_vsync_endpoint_socket:s0
+/dev/socket/property_service u:object_r:property_socket:s0
+/dev/socket/racoon u:object_r:racoon_socket:s0
+/dev/socket/recovery u:object_r:recovery_socket:s0
+/dev/socket/rild u:object_r:rild_socket:s0
+/dev/socket/rild-debug u:object_r:rild_debug_socket:s0
+/dev/socket/snapuserd u:object_r:snapuserd_socket:s0
+/dev/socket/tombstoned_crash u:object_r:tombstoned_crash_socket:s0
+/dev/socket/tombstoned_java_trace u:object_r:tombstoned_java_trace_socket:s0
+/dev/socket/tombstoned_intercept u:object_r:tombstoned_intercept_socket:s0
+/dev/socket/traced_consumer u:object_r:traced_consumer_socket:s0
+/dev/socket/traced_perf u:object_r:traced_perf_socket:s0
+/dev/socket/traced_producer u:object_r:traced_producer_socket:s0
+/dev/socket/heapprofd u:object_r:heapprofd_socket:s0
+/dev/socket/uncrypt u:object_r:uncrypt_socket:s0
+/dev/socket/wpa_eth[0-9] u:object_r:wpa_socket:s0
+/dev/socket/wpa_wlan[0-9] u:object_r:wpa_socket:s0
+/dev/socket/zygote u:object_r:zygote_socket:s0
+/dev/socket/zygote_secondary u:object_r:zygote_socket:s0
+/dev/socket/usap_pool_primary u:object_r:zygote_socket:s0
+/dev/socket/usap_pool_secondary u:object_r:zygote_socket:s0
+/dev/spdif_out.* u:object_r:audio_device:s0
+/dev/tty u:object_r:owntty_device:s0
+/dev/tty[0-9]* u:object_r:tty_device:s0
+/dev/ttyS[0-9]* u:object_r:serial_device:s0
+/dev/ttyUSB[0-9]* u:object_r:usb_serial_device:s0
+/dev/ttyACM[0-9]* u:object_r:usb_serial_device:s0
+/dev/tun u:object_r:tun_device:s0
+/dev/uhid u:object_r:uhid_device:s0
+/dev/uinput u:object_r:uhid_device:s0
+/dev/uio[0-9]* u:object_r:uio_device:s0
+/dev/urandom u:object_r:random_device:s0
+/dev/usb_accessory u:object_r:usbaccessory_device:s0
+/dev/v4l-touch[0-9]* u:object_r:input_device:s0
+/dev/video[0-9]* u:object_r:video_device:s0
+/dev/vndbinder u:object_r:vndbinder_device:s0
+/dev/watchdog u:object_r:watchdog_device:s0
+/dev/xt_qtaguid u:object_r:qtaguid_device:s0
+/dev/zero u:object_r:zero_device:s0
+/dev/__properties__ u:object_r:properties_device:s0
+/dev/__properties__/property_info u:object_r:property_info:s0
+#############################
+# Linker configuration
+#
+/linkerconfig(/.*)? u:object_r:linkerconfig_file:s0
+#############################
+# System files
+#
+/system(/.*)? u:object_r:system_file:s0
+/system/apex/com.android.art u:object_r:art_apex_dir:s0
+/system/lib(64)?(/.*)? u:object_r:system_lib_file:s0
+/system/lib(64)?/bootstrap(/.*)? u:object_r:system_bootstrap_lib_file:s0
+/system/bin/atrace u:object_r:atrace_exec:s0
+/system/bin/auditctl u:object_r:auditctl_exec:s0
+/system/bin/bcc u:object_r:rs_exec:s0
+/system/bin/blank_screen u:object_r:blank_screen_exec:s0
+/system/bin/boringssl_self_test(32|64) u:object_r:boringssl_self_test_exec:s0
+/system/bin/charger u:object_r:charger_exec:s0
+/system/bin/canhalconfigurator u:object_r:canhalconfigurator_exec:s0
+/system/bin/e2fsdroid u:object_r:e2fs_exec:s0
+/system/bin/mke2fs u:object_r:e2fs_exec:s0
+/system/bin/e2fsck -- u:object_r:fsck_exec:s0
+/system/bin/fsck\.exfat -- u:object_r:fsck_exec:s0
+/system/bin/fsck\.f2fs -- u:object_r:fsck_exec:s0
+/system/bin/init u:object_r:init_exec:s0
+# TODO(/123600489): merge mini-keyctl into toybox
+/system/bin/mini-keyctl -- u:object_r:toolbox_exec:s0
+/system/bin/fsverity_init u:object_r:fsverity_init_exec:s0
+/system/bin/sload_f2fs -- u:object_r:e2fs_exec:s0
+/system/bin/make_f2fs -- u:object_r:e2fs_exec:s0
+/system/bin/fsck_msdos -- u:object_r:fsck_exec:s0
+/system/bin/tcpdump -- u:object_r:tcpdump_exec:s0
+/system/bin/tune2fs -- u:object_r:fsck_exec:s0
+/system/bin/resize2fs -- u:object_r:fsck_exec:s0
+/system/bin/toolbox -- u:object_r:toolbox_exec:s0
+/system/bin/toybox -- u:object_r:toolbox_exec:s0
+/system/bin/ld\.mc u:object_r:rs_exec:s0
+/system/bin/logcat -- u:object_r:logcat_exec:s0
+/system/bin/logcatd -- u:object_r:logcat_exec:s0
+/system/bin/sh -- u:object_r:shell_exec:s0
+/system/bin/run-as -- u:object_r:runas_exec:s0
+/system/bin/bootanimation u:object_r:bootanim_exec:s0
+/system/bin/bootstat u:object_r:bootstat_exec:s0
+/system/bin/app_process32 u:object_r:zygote_exec:s0
+/system/bin/app_process64 u:object_r:zygote_exec:s0
+/system/bin/servicemanager u:object_r:servicemanager_exec:s0
+/system/bin/hwservicemanager u:object_r:hwservicemanager_exec:s0
+/system/bin/surfaceflinger u:object_r:surfaceflinger_exec:s0
+/system/bin/gpuservice u:object_r:gpuservice_exec:s0
+/system/bin/bufferhubd u:object_r:bufferhubd_exec:s0
+/system/bin/performanced u:object_r:performanced_exec:s0
+/system/bin/drmserver u:object_r:drmserver_exec:s0
+/system/bin/dumpstate u:object_r:dumpstate_exec:s0
+/system/bin/incident u:object_r:incident_exec:s0
+/system/bin/incidentd u:object_r:incidentd_exec:s0
+/system/bin/incident_helper u:object_r:incident_helper_exec:s0
+/system/bin/iw u:object_r:iw_exec:s0
+/system/bin/netutils-wrapper-1\.0 u:object_r:netutils_wrapper_exec:s0
+/system/bin/vold u:object_r:vold_exec:s0
+/system/bin/netd u:object_r:netd_exec:s0
+/system/bin/wificond u:object_r:wificond_exec:s0
+/system/bin/audioserver u:object_r:audioserver_exec:s0
+/system/bin/mediadrmserver u:object_r:mediadrmserver_exec:s0
+/system/bin/mediaserver u:object_r:mediaserver_exec:s0
+/system/bin/mediametrics u:object_r:mediametrics_exec:s0
+/system/bin/cameraserver u:object_r:cameraserver_exec:s0
+/system/bin/mediaextractor u:object_r:mediaextractor_exec:s0
+/system/bin/mediaswcodec u:object_r:mediaswcodec_exec:s0
+/system/bin/mediatranscoding u:object_r:mediatranscoding_exec:s0
+/system/bin/mediatuner u:object_r:mediatuner_exec:s0
+/system/bin/mdnsd u:object_r:mdnsd_exec:s0
+/system/bin/installd u:object_r:installd_exec:s0
+/system/bin/otapreopt_chroot u:object_r:otapreopt_chroot_exec:s0
+/system/bin/otapreopt_slot u:object_r:otapreopt_slot_exec:s0
+/system/bin/credstore u:object_r:credstore_exec:s0
+/system/bin/keystore u:object_r:keystore_exec:s0
+/system/bin/keystore2 u:object_r:keystore_exec:s0
+/system/bin/fingerprintd u:object_r:fingerprintd_exec:s0
+/system/bin/gatekeeperd u:object_r:gatekeeperd_exec:s0
+/system/bin/tombstoned u:object_r:tombstoned_exec:s0
+/system/bin/recovery-persist u:object_r:recovery_persist_exec:s0
+/system/bin/recovery-refresh u:object_r:recovery_refresh_exec:s0
+/system/bin/sdcard u:object_r:sdcardd_exec:s0
+/system/bin/snapshotctl u:object_r:snapshotctl_exec:s0
+/system/bin/dhcpcd u:object_r:dhcp_exec:s0
+/system/bin/dhcpcd-6\.8\.2 u:object_r:dhcp_exec:s0
+/system/bin/mtpd u:object_r:mtp_exec:s0
+/system/bin/pppd u:object_r:ppp_exec:s0
+/system/bin/racoon u:object_r:racoon_exec:s0
+/system/xbin/su u:object_r:su_exec:s0
+/system/bin/dnsmasq u:object_r:dnsmasq_exec:s0
+/system/bin/healthd u:object_r:healthd_exec:s0
+/system/bin/clatd u:object_r:clatd_exec:s0
+/system/bin/linker(64)? u:object_r:system_linker_exec:s0
+/system/bin/linkerconfig u:object_r:linkerconfig_exec:s0
+/system/bin/bootstrap/linker(64)? u:object_r:system_linker_exec:s0
+/system/bin/bootstrap/linkerconfig u:object_r:linkerconfig_exec:s0
+/system/bin/llkd u:object_r:llkd_exec:s0
+/system/bin/lmkd u:object_r:lmkd_exec:s0
+/system/bin/usbd u:object_r:usbd_exec:s0
+/system/bin/inputflinger u:object_r:inputflinger_exec:s0
+/system/bin/logd u:object_r:logd_exec:s0
+/system/bin/lpdumpd u:object_r:lpdumpd_exec:s0
+/system/bin/rss_hwm_reset u:object_r:rss_hwm_reset_exec:s0
+/system/bin/perfetto u:object_r:perfetto_exec:s0
+/system/bin/traced u:object_r:traced_exec:s0
+/system/bin/traced_perf u:object_r:traced_perf_exec:s0
+/system/bin/traced_probes u:object_r:traced_probes_exec:s0
+/system/bin/heapprofd u:object_r:heapprofd_exec:s0
+/system/bin/uncrypt u:object_r:uncrypt_exec:s0
+/system/bin/update_verifier u:object_r:update_verifier_exec:s0
+/system/bin/logwrapper u:object_r:system_file:s0
+/system/bin/vdc u:object_r:vdc_exec:s0
+/system/bin/cppreopts\.sh u:object_r:cppreopts_exec:s0
+/system/bin/preloads_copy\.sh u:object_r:preloads_copy_exec:s0
+/system/bin/preopt2cachename u:object_r:preopt2cachename_exec:s0
+/system/bin/viewcompiler u:object_r:viewcompiler_exec:s0
+/system/bin/iorapd u:object_r:iorapd_exec:s0
+/system/bin/iorap\.inode2filename u:object_r:iorap_inode2filename_exec:s0
+/system/bin/iorap\.prefetcherd u:object_r:iorap_prefetcherd_exec:s0
+/system/bin/sgdisk u:object_r:sgdisk_exec:s0
+/system/bin/blkid u:object_r:blkid_exec:s0
+/system/bin/tzdatacheck u:object_r:tzdatacheck_exec:s0
+/system/bin/flags_health_check -- u:object_r:flags_health_check_exec:s0
+/system/bin/idmap u:object_r:idmap_exec:s0
+/system/bin/idmap2(d)? u:object_r:idmap_exec:s0
+/system/bin/update_engine u:object_r:update_engine_exec:s0
+/system/bin/profcollectd u:object_r:profcollectd_exec:s0
+/system/bin/profcollectctl u:object_r:profcollectd_exec:s0
+/system/bin/storaged u:object_r:storaged_exec:s0
+/system/bin/wpantund u:object_r:wpantund_exec:s0
+/system/bin/virtual_touchpad u:object_r:virtual_touchpad_exec:s0
+/system/bin/hw/android\.frameworks\.bufferhub@1\.0-service u:object_r:fwk_bufferhub_exec:s0
+/system/bin/hw/android\.hidl\.allocator@1\.0-service u:object_r:hal_allocator_default_exec:s0
+/system/bin/hw/android\.system\.suspend@1\.0-service u:object_r:system_suspend_exec:s0
+/system/etc/cgroups\.json u:object_r:cgroup_desc_file:s0
+/system/etc/task_profiles/cgroups_[0-9]+\.json u:object_r:cgroup_desc_api_file:s0
+/system/etc/event-log-tags u:object_r:system_event_log_tags_file:s0
+/system/etc/group u:object_r:system_group_file:s0
+/system/etc/ld\.config.* u:object_r:system_linker_config_file:s0
+/system/etc/passwd u:object_r:system_passwd_file:s0
+/system/etc/seccomp_policy(/.*)? u:object_r:system_seccomp_policy_file:s0
+/system/etc/security/cacerts(/.*)? u:object_r:system_security_cacerts_file:s0
+/system/etc/selinux/mapping/[0-9]+\.[0-9]+\.cil u:object_r:sepolicy_file:s0
+/system/etc/selinux/plat_mac_permissions\.xml u:object_r:mac_perms_file:s0
+/system/etc/selinux/plat_property_contexts u:object_r:property_contexts_file:s0
+/system/etc/selinux/plat_service_contexts u:object_r:service_contexts_file:s0
+/system/etc/selinux/plat_hwservice_contexts u:object_r:hwservice_contexts_file:s0
+/system/etc/selinux/plat_keystore2_key_contexts u:object_r:keystore2_key_contexts_file:s0
+/system/etc/selinux/plat_file_contexts u:object_r:file_contexts_file:s0
+/system/etc/selinux/plat_seapp_contexts u:object_r:seapp_contexts_file:s0
+/system/etc/selinux/plat_sepolicy\.cil u:object_r:sepolicy_file:s0
+/system/etc/selinux/plat_and_mapping_sepolicy\.cil\.sha256 u:object_r:sepolicy_file:s0
+/system/etc/task_profiles\.json u:object_r:task_profiles_file:s0
+/system/etc/task_profiles/task_profiles_[0-9]+\.json u:object_r:task_profiles_api_file:s0
+/system/usr/share/zoneinfo(/.*)? u:object_r:system_zoneinfo_file:s0
+/system/bin/vr_hwc u:object_r:vr_hwc_exec:s0
+/system/bin/adbd u:object_r:adbd_exec:s0
+/system/bin/vold_prepare_subdirs u:object_r:vold_prepare_subdirs_exec:s0
+/system/bin/stats u:object_r:stats_exec:s0
+/system/bin/statsd u:object_r:statsd_exec:s0
+/system/bin/bpfloader u:object_r:bpfloader_exec:s0
+/system/bin/wait_for_keymaster u:object_r:wait_for_keymaster_exec:s0
+/system/bin/watchdogd u:object_r:watchdogd_exec:s0
+/system/bin/apexd u:object_r:apexd_exec:s0
+/system/bin/gsid u:object_r:gsid_exec:s0
+/system/bin/simpleperf u:object_r:simpleperf_exec:s0
+/system/bin/simpleperf_app_runner u:object_r:simpleperf_app_runner_exec:s0
+/system/bin/notify_traceur\.sh u:object_r:notify_traceur_exec:s0
+/system/bin/migrate_legacy_obb_data\.sh u:object_r:migrate_legacy_obb_data_exec:s0
+/system/bin/android\.frameworks\.automotive\.display@1\.0-service u:object_r:automotive_display_service_exec:s0
+/system/bin/snapuserd u:object_r:snapuserd_exec:s0
+
+#############################
+# Vendor files
+#
+/(vendor|system/vendor)(/.*)? u:object_r:vendor_file:s0
+/(vendor|system/vendor)/bin/sh u:object_r:vendor_shell_exec:s0
+/(vendor|system/vendor)/bin/toybox_vendor u:object_r:vendor_toolbox_exec:s0
+/(vendor|system/vendor)/bin/toolbox u:object_r:vendor_toolbox_exec:s0
+/(vendor|system/vendor)/etc(/.*)? u:object_r:vendor_configs_file:s0
+/(vendor|system/vendor)/etc/cgroups\.json u:object_r:vendor_cgroup_desc_file:s0
+/(vendor|system/vendor)/etc/task_profiles\.json u:object_r:vendor_task_profiles_file:s0
+
+/(vendor|system/vendor)/lib(64)?/egl(/.*)? u:object_r:same_process_hal_file:s0
+
+/(vendor|system/vendor)/lib(64)?/vndk-sp(/.*)? u:object_r:vndk_sp_file:s0
+
+/(vendor|system/vendor)/manifest\.xml u:object_r:vendor_configs_file:s0
+/(vendor|system/vendor)/compatibility_matrix\.xml u:object_r:vendor_configs_file:s0
+/(vendor|system/vendor)/etc/vintf(/.*)? u:object_r:vendor_configs_file:s0
+/(vendor|system/vendor)/app(/.*)? u:object_r:vendor_app_file:s0
+/(vendor|system/vendor)/priv-app(/.*)? u:object_r:vendor_app_file:s0
+/(vendor|system/vendor)/overlay(/.*)? u:object_r:vendor_overlay_file:s0
+/(vendor|system/vendor)/framework(/.*)? u:object_r:vendor_framework_file:s0
+
+/(vendor|system/vendor)/apex(/[^/]+){0,2} u:object_r:vendor_apex_file:s0
+/(vendor|system/vendor)/bin/misc_writer u:object_r:vendor_misc_writer_exec:s0
+/(vendor|system/vendor)/bin/boringssl_self_test(32|64) u:object_r:vendor_boringssl_self_test_exec:s0
+
+# HAL location
+/(vendor|system/vendor)/lib(64)?/hw u:object_r:vendor_hal_file:s0
+
+/(vendor|system/vendor)/etc/selinux/nonplat_service_contexts u:object_r:nonplat_service_contexts_file:s0
+
+/(vendor|system/vendor)/etc/selinux/vendor_service_contexts u:object_r:vendor_service_contexts_file:s0
+
+/(vendor|system/vendor)/bin/install-recovery\.sh u:object_r:vendor_install_recovery_exec:s0
+
+#############################
+# OEM and ODM files
+#
+/(odm|vendor/odm)(/.*)? u:object_r:vendor_file:s0
+/(odm|vendor/odm)/lib(64)?/egl(/.*)? u:object_r:same_process_hal_file:s0
+/(odm|vendor/odm)/lib(64)?/hw u:object_r:vendor_hal_file:s0
+/(odm|vendor/odm)/lib(64)?/vndk-sp(/.*)? u:object_r:vndk_sp_file:s0
+/(odm|vendor/odm)/bin/sh u:object_r:vendor_shell_exec:s0
+/(odm|vendor/odm)/etc(/.*)? u:object_r:vendor_configs_file:s0
+/(odm|vendor/odm)/app(/.*)? u:object_r:vendor_app_file:s0
+/(odm|vendor/odm)/priv-app(/.*)? u:object_r:vendor_app_file:s0
+/(odm|vendor/odm)/overlay(/.*)? u:object_r:vendor_overlay_file:s0
+/(odm|vendor/odm)/framework(/.*)? u:object_r:vendor_framework_file:s0
+
+# Input configuration
+/(odm|vendor/odm|vendor|system/vendor)/usr/keylayout(/.*)?\.kl u:object_r:vendor_keylayout_file:s0
+/(odm|vendor/odm|vendor|system/vendor)/usr/keychars(/.*)?\.kcm u:object_r:vendor_keychars_file:s0
+/(odm|vendor/odm|vendor|system/vendor)/usr/idc(/.*)?\.idc u:object_r:vendor_idc_file:s0
+
+/oem(/.*)? u:object_r:oemfs:s0
+/oem/overlay(/.*)? u:object_r:vendor_overlay_file:s0
+
+# The precompiled monolithic sepolicy will be under /odm only when
+# BOARD_USES_ODMIMAGE is true: a separate odm.img is built.
+/odm/etc/selinux/precompiled_sepolicy u:object_r:sepolicy_file:s0
+/odm/etc/selinux/precompiled_sepolicy\.plat_and_mapping\.sha256 u:object_r:sepolicy_file:s0
+
+/(odm|vendor/odm)/etc/selinux/odm_sepolicy\.cil u:object_r:sepolicy_file:s0
+/(odm|vendor/odm)/etc/selinux/odm_file_contexts u:object_r:file_contexts_file:s0
+/(odm|vendor/odm)/etc/selinux/odm_seapp_contexts u:object_r:seapp_contexts_file:s0
+/(odm|vendor/odm)/etc/selinux/odm_property_contexts u:object_r:property_contexts_file:s0
+/(odm|vendor/odm)/etc/selinux/odm_hwservice_contexts u:object_r:hwservice_contexts_file:s0
+/(odm|vendor/odm)/etc/selinux/odm_keystore2_key_contexts u:object_r:keystore2_key_contexts_file:s0
+/(odm|vendor/odm)/etc/selinux/odm_mac_permissions\.xml u:object_r:mac_perms_file:s0
+
+#############################
+# Product files
+#
+/(product|system/product)(/.*)? u:object_r:system_file:s0
+/(product|system/product)/etc/group u:object_r:system_group_file:s0
+/(product|system/product)/etc/passwd u:object_r:system_passwd_file:s0
+/(product|system/product)/overlay(/.*)? u:object_r:vendor_overlay_file:s0
+
+/(product|system/product)/etc/selinux/product_file_contexts u:object_r:file_contexts_file:s0
+/(product|system/product)/etc/selinux/product_hwservice_contexts u:object_r:hwservice_contexts_file:s0
+/(product|system/product)/etc/selinux/product_keystore2_key_contexts u:object_r:keystore2_key_contexts_file:s0
+/(product|system/product)/etc/selinux/product_property_contexts u:object_r:property_contexts_file:s0
+/(product|system/product)/etc/selinux/product_seapp_contexts u:object_r:seapp_contexts_file:s0
+/(product|system/product)/etc/selinux/product_service_contexts u:object_r:service_contexts_file:s0
+/(product|system/product)/etc/selinux/product_mac_permissions\.xml u:object_r:mac_perms_file:s0
+
+/(product|system/product)/lib(64)?(/.*)? u:object_r:system_lib_file:s0
+
+#############################
+# SystemExt files
+#
+/(system_ext|system/system_ext)(/.*)? u:object_r:system_file:s0
+/(system_ext|system/system_ext)/etc/group u:object_r:system_group_file:s0
+/(system_ext|system/system_ext)/etc/passwd u:object_r:system_passwd_file:s0
+/(system_ext|system/system_ext)/overlay(/.*)? u:object_r:vendor_overlay_file:s0
+
+/(system_ext|system/system_ext)/etc/selinux/system_ext_file_contexts u:object_r:file_contexts_file:s0
+/(system_ext|system/system_ext)/etc/selinux/system_ext_hwservice_contexts u:object_r:hwservice_contexts_file:s0
+/(system_ext|system/system_ext)/etc/selinux/system_ext_keystore2_key_contexts u:object_r:keystore2_key_contexts_file:s0
+/(system_ext|system/system_ext)/etc/selinux/system_ext_property_contexts u:object_r:property_contexts_file:s0
+/(system_ext|system/system_ext)/etc/selinux/system_ext_seapp_contexts u:object_r:seapp_contexts_file:s0
+/(system_ext|system/system_ext)/etc/selinux/system_ext_service_contexts u:object_r:service_contexts_file:s0
+/(system_ext|system/system_ext)/etc/selinux/system_ext_mac_permissions\.xml u:object_r:mac_perms_file:s0
+
+/(system_ext|system/system_ext)/bin/aidl_lazy_test_server u:object_r:aidl_lazy_test_server_exec:s0
+/(system_ext|system/system_ext)/bin/hidl_lazy_test_server u:object_r:hidl_lazy_test_server_exec:s0
+
+/(system_ext|system/system_ext)/lib(64)?(/.*)? u:object_r:system_lib_file:s0
+
+#############################
+# VendorDlkm files
+# This includes VENDOR Dynamically Loadable Kernel Modules and other misc files.
+#
+/(vendor_dlkm|vendor/vendor_dlkm|system/vendor/vendor_dlkm)(/.*)? u:object_r:vendor_file:s0
+
+#############################
+# OdmDlkm files
+# This includes ODM Dynamically Loadable Kernel Modules and other misc files.
+#
+/(odm_dlkm|vendor/odm_dlkm|system/vendor/odm_dlkm)(/.*)? u:object_r:vendor_file:s0
+
+#############################
+# Vendor files from /(product|system/product)/vendor_overlay
+#
+# NOTE: For additional vendor file contexts for vendor overlay files,
+# use device specific file_contexts.
+#
+/(product|system/product)/vendor_overlay/[0-9]+/.* u:object_r:vendor_file:s0
+
+#############################
+# Data files
+#
+# NOTE: When modifying existing label rules, changes may also need to
+# propagate to the "Expanded data files" section.
+#
+/data u:object_r:system_data_root_file:s0
+/data/(.*)? u:object_r:system_data_file:s0
+/data/system/packages\.list u:object_r:packages_list_file:s0
+/data/unencrypted(/.*)? u:object_r:unencrypted_data_file:s0
+/data/backup(/.*)? u:object_r:backup_data_file:s0
+/data/secure/backup(/.*)? u:object_r:backup_data_file:s0
+/data/system/ndebugsocket u:object_r:system_ndebug_socket:s0
+/data/system/unsolzygotesocket u:object_r:system_unsolzygote_socket:s0
+/data/drm(/.*)? u:object_r:drm_data_file:s0
+/data/resource-cache(/.*)? u:object_r:resourcecache_data_file:s0
+/data/dalvik-cache(/.*)? u:object_r:dalvikcache_data_file:s0
+/data/ota(/.*)? u:object_r:ota_data_file:s0
+/data/ota_package(/.*)? u:object_r:ota_package_file:s0
+/data/adb(/.*)? u:object_r:adb_data_file:s0
+/data/anr(/.*)? u:object_r:anr_data_file:s0
+/data/apex(/.*)? u:object_r:apex_data_file:s0
+/data/apex/active/(.*)? u:object_r:staging_data_file:s0
+/data/apex/backup/(.*)? u:object_r:staging_data_file:s0
+/data/app(/.*)? u:object_r:apk_data_file:s0
+# Traditional /data/app/[packageName]-[randomString]/base.apk location
+/data/app/[^/]+/oat(/.*)? u:object_r:dalvikcache_data_file:s0
+# /data/app/[randomStringA]/[packageName]-[randomStringB]/base.apk layout
+/data/app/[^/]+/[^/]+/oat(/.*)? u:object_r:dalvikcache_data_file:s0
+/data/app/vmdl[^/]+\.tmp(/.*)? u:object_r:apk_tmp_file:s0
+/data/app/vmdl[^/]+\.tmp/oat(/.*)? u:object_r:dalvikcache_data_file:s0
+/data/app-private(/.*)? u:object_r:apk_private_data_file:s0
+/data/app-private/vmdl.*\.tmp(/.*)? u:object_r:apk_private_tmp_file:s0
+/data/gsi(/.*)? u:object_r:gsi_data_file:s0
+/data/gsi/ota(/.*)? u:object_r:ota_image_data_file:s0
+/data/tombstones(/.*)? u:object_r:tombstone_data_file:s0
+/data/vendor/tombstones/wifi(/.*)? u:object_r:tombstone_wifi_data_file:s0
+/data/local/tests(/.*)? u:object_r:shell_test_data_file:s0
+/data/local/tmp(/.*)? u:object_r:shell_data_file:s0
+/data/local/tmp/ltp(/.*)? u:object_r:nativetest_data_file:s0
+/data/local/traces(/.*)? u:object_r:trace_data_file:s0
+/data/media(/.*)? u:object_r:media_rw_data_file:s0
+/data/mediadrm(/.*)? u:object_r:media_data_file:s0
+/data/nativetest(/.*)? u:object_r:nativetest_data_file:s0
+/data/nativetest64(/.*)? u:object_r:nativetest_data_file:s0
+# This directory was removed after Q Beta 2, but we need to preserve labels for upgrading devices.
+/data/pkg_staging(/.*)? u:object_r:staging_data_file:s0
+/data/property(/.*)? u:object_r:property_data_file:s0
+/data/preloads(/.*)? u:object_r:preloads_data_file:s0
+/data/preloads/media(/.*)? u:object_r:preloads_media_file:s0
+/data/preloads/demo(/.*)? u:object_r:preloads_media_file:s0
+/data/server_configurable_flags(/.*)? u:object_r:server_configurable_flags_data_file:s0
+/data/app-staging(/.*)? u:object_r:staging_data_file:s0
+# Ensure we have the same labels as /data/app or /data/apex/active
+# to avoid restorecon conflicts
+/data/rollback/\d+/[^/]+/.*\.apk u:object_r:apk_data_file:s0
+/data/rollback/\d+/[^/]+/.*\.apex u:object_r:staging_data_file:s0
+/data/fonts/files(/.*)? u:object_r:font_data_file:s0
+
+# Misc data
+/data/misc/adb(/.*)? u:object_r:adb_keys_file:s0
+/data/misc/apexdata(/.*)? u:object_r:apex_module_data_file:s0
+/data/misc/apexdata/com\.android\.art(/.*)? u:object_r:apex_art_data_file:s0
+/data/misc/apexdata/com\.android\.permission(/.*)? u:object_r:apex_permission_data_file:s0
+/data/misc/apexdata/com\.android\.wifi(/.*)? u:object_r:apex_wifi_data_file:s0
+/data/misc/apexrollback(/.*)? u:object_r:apex_rollback_data_file:s0
+/data/misc/apns(/.*)? u:object_r:radio_data_file:s0
+/data/misc/appcompat(/.*)? u:object_r:appcompat_data_file:s0
+/data/misc/audio(/.*)? u:object_r:audio_data_file:s0
+/data/misc/audioserver(/.*)? u:object_r:audioserver_data_file:s0
+/data/misc/audiohal(/.*)? u:object_r:audiohal_data_file:s0
+/data/misc/bootstat(/.*)? u:object_r:bootstat_data_file:s0
+/data/misc/boottrace(/.*)? u:object_r:boottrace_data_file:s0
+/data/misc/bluetooth(/.*)? u:object_r:bluetooth_data_file:s0
+/data/misc/bluetooth/logs(/.*)? u:object_r:bluetooth_logs_data_file:s0
+/data/misc/bluedroid(/.*)? u:object_r:bluetooth_data_file:s0
+/data/misc/bluedroid/\.a2dp_ctrl u:object_r:bluetooth_socket:s0
+/data/misc/bluedroid/\.a2dp_data u:object_r:bluetooth_socket:s0
+/data/misc/camera(/.*)? u:object_r:camera_data_file:s0
+/data/misc/carrierid(/.*)? u:object_r:radio_data_file:s0
+/data/misc/dhcp(/.*)? u:object_r:dhcp_data_file:s0
+/data/misc/dhcp-6\.8\.2(/.*)? u:object_r:dhcp_data_file:s0
+/data/misc/emergencynumberdb(/.*)? u:object_r:emergency_data_file:s0
+/data/misc/gatekeeper(/.*)? u:object_r:gatekeeper_data_file:s0
+/data/misc/incidents(/.*)? u:object_r:incident_data_file:s0
+/data/misc/installd(/.*)? u:object_r:install_data_file:s0
+/data/misc/keychain(/.*)? u:object_r:keychain_data_file:s0
+/data/misc/credstore(/.*)? u:object_r:credstore_data_file:s0
+/data/misc/keystore(/.*)? u:object_r:keystore_data_file:s0
+/data/misc/logd(/.*)? u:object_r:misc_logd_file:s0
+/data/misc/media(/.*)? u:object_r:media_data_file:s0
+/data/misc/net(/.*)? u:object_r:net_data_file:s0
+/data/misc/network_watchlist(/.*)? u:object_r:network_watchlist_data_file:s0
+/data/misc/nfc/logs(/.*)? u:object_r:nfc_logs_data_file:s0
+/data/misc/perfetto-traces/bugreport(.*)? u:object_r:perfetto_traces_bugreport_data_file:s0
+/data/misc/perfetto-traces(/.*)? u:object_r:perfetto_traces_data_file:s0
+/data/misc/perfetto-configs(/.*)? u:object_r:perfetto_configs_data_file:s0
+/data/misc/prereboot(/.*)? u:object_r:prereboot_data_file:s0
+/data/misc/profcollectd(/.*)? u:object_r:profcollectd_data_file:s0
+/data/misc/radio(/.*)? u:object_r:radio_core_data_file:s0
+/data/misc/recovery(/.*)? u:object_r:recovery_data_file:s0
+/data/misc/shared_relro(/.*)? u:object_r:shared_relro_file:s0
+/data/misc/sms(/.*)? u:object_r:radio_data_file:s0
+/data/misc/snapshotctl_log(/.*)? u:object_r:snapshotctl_log_data_file:s0
+/data/misc/stats-active-metric(/.*)? u:object_r:stats_data_file:s0
+/data/misc/stats-data(/.*)? u:object_r:stats_data_file:s0
+/data/misc/stats-service(/.*)? u:object_r:stats_data_file:s0
+/data/misc/stats-metadata(/.*)? u:object_r:stats_data_file:s0
+/data/misc/systemkeys(/.*)? u:object_r:systemkeys_data_file:s0
+/data/misc/textclassifier(/.*)? u:object_r:textclassifier_data_file:s0
+/data/misc/train-info(/.*)? u:object_r:stats_data_file:s0
+/data/misc/user(/.*)? u:object_r:misc_user_data_file:s0
+/data/misc/vpn(/.*)? u:object_r:vpn_data_file:s0
+/data/misc/wifi(/.*)? u:object_r:wifi_data_file:s0
+/data/misc_ce/[0-9]+/wifi(/.*)? u:object_r:wifi_data_file:s0
+/data/misc/wifi/sockets(/.*)? u:object_r:wpa_socket:s0
+/data/misc/wifi/sockets/wpa_ctrl.* u:object_r:system_wpa_socket:s0
+/data/misc/zoneinfo(/.*)? u:object_r:zoneinfo_data_file:s0
+/data/misc/vold(/.*)? u:object_r:vold_data_file:s0
+/data/misc/iorapd(/.*)? u:object_r:iorapd_data_file:s0
+/data/misc/update_engine(/.*)? u:object_r:update_engine_data_file:s0
+/data/misc/update_engine_log(/.*)? u:object_r:update_engine_log_data_file:s0
+/data/system/dropbox(/.*)? u:object_r:dropbox_data_file:s0
+/data/system/heapdump(/.*)? u:object_r:heapdump_data_file:s0
+/data/misc/trace(/.*)? u:object_r:method_trace_data_file:s0
+/data/misc/wmtrace(/.*)? u:object_r:wm_trace_data_file:s0
+# TODO(calin) label profile reference differently so that only
+# profman run as a special user can write to them
+/data/misc/profiles/cur(/[0-9]+)? u:object_r:user_profile_root_file:s0
+/data/misc/profiles/cur/[0-9]+/.* u:object_r:user_profile_data_file:s0
+/data/misc/profiles/ref(/.*)? u:object_r:user_profile_data_file:s0
+/data/misc/profman(/.*)? u:object_r:profman_dump_data_file:s0
+/data/vendor(/.*)? u:object_r:vendor_data_file:s0
+/data/vendor_ce(/.*)? u:object_r:vendor_data_file:s0
+/data/vendor_de(/.*)? u:object_r:vendor_data_file:s0
+
+# storaged proto files
+/data/misc_de/[0-9]+/storaged(/.*)? u:object_r:storaged_data_file:s0
+/data/misc_ce/[0-9]+/storaged(/.*)? u:object_r:storaged_data_file:s0
+
+# Fingerprint data
+/data/system/users/[0-9]+/fpdata(/.*)? u:object_r:fingerprintd_data_file:s0
+
+# Fingerprint vendor data file
+/data/vendor_de/[0-9]+/fpdata(/.*)? u:object_r:fingerprint_vendor_data_file:s0
+
+# Face vendor data file
+/data/vendor_de/[0-9]+/facedata(/.*)? u:object_r:face_vendor_data_file:s0
+/data/vendor_ce/[0-9]+/facedata(/.*)? u:object_r:face_vendor_data_file:s0
+
+# Iris vendor data file
+/data/vendor_de/[0-9]+/irisdata(/.*)? u:object_r:iris_vendor_data_file:s0
+
+# Bootchart data
+/data/bootchart(/.*)? u:object_r:bootchart_data_file:s0
+
+# App data snapshots (managed by installd).
+/data/misc_de/[0-9]+/rollback(/.*)? u:object_r:rollback_data_file:s0
+/data/misc_ce/[0-9]+/rollback(/.*)? u:object_r:rollback_data_file:s0
+
+# Apex data directories
+/data/misc_de/[0-9]+/apexdata(/.*)? u:object_r:apex_module_data_file:s0
+/data/misc_ce/[0-9]+/apexdata(/.*)? u:object_r:apex_module_data_file:s0
+/data/misc_de/[0-9]+/apexdata/com\.android\.permission(/.*)? u:object_r:apex_permission_data_file:s0
+/data/misc_ce/[0-9]+/apexdata/com\.android\.permission(/.*)? u:object_r:apex_permission_data_file:s0
+/data/misc_de/[0-9]+/apexdata/com\.android\.wifi(/.*)? u:object_r:apex_wifi_data_file:s0
+/data/misc_ce/[0-9]+/apexdata/com\.android\.wifi(/.*)? u:object_r:apex_wifi_data_file:s0
+
+# Apex rollback directories
+/data/misc_de/[0-9]+/apexrollback(/.*)? u:object_r:apex_rollback_data_file:s0
+/data/misc_ce/[0-9]+/apexrollback(/.*)? u:object_r:apex_rollback_data_file:s0
+
+# Incremental directories
+/data/incremental(/.*)? u:object_r:apk_data_file:s0
+/data/incremental/MT_[^/]+/mount/.pending_reads u:object_r:incremental_control_file:s0
+/data/incremental/MT_[^/]+/mount/.log u:object_r:incremental_control_file:s0
+/data/incremental/MT_[^/]+/mount/.blocks_written u:object_r:incremental_control_file:s0
+
+#############################
+# Expanded data files
+#
+/mnt/expand(/.*)? u:object_r:mnt_expand_file:s0
+/mnt/expand/[^/]+(/.*)? u:object_r:system_data_file:s0
+/mnt/expand/[^/]+/app(/.*)? u:object_r:apk_data_file:s0
+/mnt/expand/[^/]+/app/[^/]+/oat(/.*)? u:object_r:dalvikcache_data_file:s0
+# /mnt/expand/..../app/[randomStringA]/[packageName]-[randomStringB]/base.apk layout
+/mnt/expand/[^/]+/app/[^/]+/[^/]+/oat(/.*)? u:object_r:dalvikcache_data_file:s0
+/mnt/expand/[^/]+/app/vmdl[^/]+\.tmp(/.*)? u:object_r:apk_tmp_file:s0
+/mnt/expand/[^/]+/app/vmdl[^/]+\.tmp/oat(/.*)? u:object_r:dalvikcache_data_file:s0
+/mnt/expand/[^/]+/local/tmp(/.*)? u:object_r:shell_data_file:s0
+/mnt/expand/[^/]+/media(/.*)? u:object_r:media_rw_data_file:s0
+/mnt/expand/[^/]+/misc/vold(/.*)? u:object_r:vold_data_file:s0
+
+# coredump directory for userdebug/eng devices
+/cores(/.*)? u:object_r:coredump_file:s0
+
+# Wallpaper files
+/data/system/users/[0-9]+/wallpaper_lock_orig u:object_r:wallpaper_file:s0
+/data/system/users/[0-9]+/wallpaper_lock u:object_r:wallpaper_file:s0
+/data/system/users/[0-9]+/wallpaper_orig u:object_r:wallpaper_file:s0
+/data/system/users/[0-9]+/wallpaper u:object_r:wallpaper_file:s0
+
+# Ringtone files
+/data/system_de/[0-9]+/ringtones(/.*)? u:object_r:ringtone_file:s0
+
+# ShortcutManager icons, e.g.
+# /data/system_ce/0/shortcut_service/bitmaps/com.example.app/1457472879282.png
+/data/system_ce/[0-9]+/shortcut_service/bitmaps(/.*)? u:object_r:shortcut_manager_icons:s0
+
+# User icon files
+/data/system/users/[0-9]+/photo\.png u:object_r:icon_file:s0
+
+# vold per-user data
+/data/misc_de/[0-9]+/vold(/.*)? u:object_r:vold_data_file:s0
+/data/misc_ce/[0-9]+/vold(/.*)? u:object_r:vold_data_file:s0
+
+# iorapd per-user data
+/data/misc_ce/[0-9]+/iorapd(/.*)? u:object_r:iorapd_data_file:s0
+
+# Backup service persistent per-user bookkeeping
+/data/system_ce/[0-9]+/backup(/.*)? u:object_r:backup_data_file:s0
+# Backup service temporary per-user data for inter-change with apps
+/data/system_ce/[0-9]+/backup_stage(/.*)? u:object_r:backup_data_file:s0
+
+#############################
+# efs files
+#
+/efs(/.*)? u:object_r:efs_file:s0
+
+#############################
+# Cache files
+#
+/cache(/.*)? u:object_r:cache_file:s0
+/cache/recovery(/.*)? u:object_r:cache_recovery_file:s0
+# General backup/restore interchange with apps
+/cache/backup_stage(/.*)? u:object_r:cache_backup_file:s0
+# LocalTransport (backup) uses this subtree
+/cache/backup(/.*)? u:object_r:cache_private_backup_file:s0
+
+#############################
+# Overlayfs support directories
+#
+/cache/overlay(/.*)? u:object_r:overlayfs_file:s0
+/mnt/scratch(/.*)? u:object_r:overlayfs_file:s0
+
+/data/cache(/.*)? u:object_r:cache_file:s0
+/data/cache/recovery(/.*)? u:object_r:cache_recovery_file:s0
+# General backup/restore interchange with apps
+/data/cache/backup_stage(/.*)? u:object_r:cache_backup_file:s0
+# LocalTransport (backup) uses this subtree
+/data/cache/backup(/.*)? u:object_r:cache_private_backup_file:s0
+
+#############################
+# Metadata files
+#
+/metadata(/.*)? u:object_r:metadata_file:s0
+/metadata/apex(/.*)? u:object_r:apex_metadata_file:s0
+/metadata/vold(/.*)? u:object_r:vold_metadata_file:s0
+/metadata/gsi(/.*)? u:object_r:gsi_metadata_file:s0
+/metadata/gsi/ota(/.*)? u:object_r:ota_metadata_file:s0
+/metadata/password_slots(/.*)? u:object_r:password_slot_metadata_file:s0
+/metadata/ota(/.*)? u:object_r:ota_metadata_file:s0
+/metadata/bootstat(/.*)? u:object_r:metadata_bootstat_file:s0
+/metadata/staged-install(/.*)? u:object_r:staged_install_file:s0
+/metadata/userspacereboot(/.*)? u:object_r:userspace_reboot_metadata_file:s0
+/metadata/watchdog(/.*)? u:object_r:watchdog_metadata_file:s0
+
+#############################
+# asec containers
+/mnt/asec(/.*)? u:object_r:asec_apk_file:s0
+/mnt/asec/[^/]+/[^/]+\.zip u:object_r:asec_public_file:s0
+/mnt/asec/[^/]+/lib(/.*)? u:object_r:asec_public_file:s0
+/data/app-asec(/.*)? u:object_r:asec_image_file:s0
+
+#############################
+# external storage
+/mnt/media_rw(/.*)? u:object_r:mnt_media_rw_file:s0
+/mnt/user(/.*)? u:object_r:mnt_user_file:s0
+/mnt/pass_through(/.*)? u:object_r:mnt_pass_through_file:s0
+/mnt/sdcard u:object_r:mnt_sdcard_file:s0
+/mnt/runtime(/.*)? u:object_r:storage_file:s0
+/storage(/.*)? u:object_r:storage_file:s0
+
+#############################
+# mount point for read-write vendor partitions
+/mnt/vendor(/.*)? u:object_r:mnt_vendor_file:s0
+
+#############################
+# mount point for read-write product partitions
+/mnt/product(/.*)? u:object_r:mnt_product_file:s0
diff --git a/tests/hostside/Android.bp b/tests/hostside/Android.bp
index 3f04a78..63b3a3d 100644
--- a/tests/hostside/Android.bp
+++ b/tests/hostside/Android.bp
@@ -12,10 +12,14 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-kernel_version = "5.4"
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+kernel_version = "5.10"
kernel_target_stem = ":kernel_prebuilts-" + kernel_version
-vendor_ramdisk_target_stem = ":cf_prebuilts_initramfs-" + kernel_version
+vendor_ramdisk_target_stem = ":virt_device_prebuilts_initramfs-" + kernel_version
// JAR containing all virtualization host-side tests.
java_test_host {
diff --git a/tests/hostside/native/init/Android.bp b/tests/hostside/native/init/Android.bp
index a98948b..4934a6d 100644
--- a/tests/hostside/native/init/Android.bp
+++ b/tests/hostside/native/init/Android.bp
@@ -12,6 +12,10 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
cc_binary {
name: "virt_hostside_tests_guest_init",
srcs: ["main.cc"],
diff --git a/tests/hostside/native/vsock/Android.bp b/tests/hostside/native/vsock/Android.bp
index cbee98d..13b46d5 100644
--- a/tests/hostside/native/vsock/Android.bp
+++ b/tests/hostside/native/vsock/Android.bp
@@ -12,6 +12,10 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
cc_test {
name: "virt_hostside_tests_vsock_server",
srcs: ["server.cc"],