Remove unnecessary local ID in authfs
AuthFS had the unnecessary flexibility to associate a local file ID /
filesystem entry name with the remote FD. Remove this flexibility since
we can always use the remote FD to name the file entry.
Also, rename some of the "id" with "fd". Although id/identifiler may
make better sense in the API, calling it fd/file descriptor could reduce
mental overhead.
Bug: 203251769
Test: atest AuthFsHostTest
Test: atest ComposHostTestCases
Change-Id: I7a75ef4ed21fb00f5c7f80c560d1f654d21268cd
diff --git a/authfs/aidl/com/android/virt/fs/IVirtFdService.aidl b/authfs/aidl/com/android/virt/fs/IVirtFdService.aidl
index e7acfd1..58ccfc3 100644
--- a/authfs/aidl/com/android/virt/fs/IVirtFdService.aidl
+++ b/authfs/aidl/com/android/virt/fs/IVirtFdService.aidl
@@ -17,8 +17,8 @@
package com.android.virt.fs;
/**
- * A service that works like a file server, where the files and directories are identified by "FD"
- * as the unique identifier.
+ * A service that works like a file server, where the files and directories are identified by
+ * "remote FD" that may be pre-exchanged or created on request.
*
* When a binder error is returned and it is a service specific error, the error code is an errno
* value which is an int.
@@ -30,45 +30,45 @@
const int MAX_REQUESTING_DATA = 16384;
/**
- * Returns the content of the given file ID, from the offset, for the amount of requested size
+ * Returns the content of the given remote FD, from the offset, for the amount of requested size
* or until EOF.
*/
- byte[] readFile(int id, long offset, int size);
+ byte[] readFile(int fd, long offset, int size);
/**
- * Returns the content of fs-verity compatible Merkle tree of the given file ID, from the
+ * Returns the content of fs-verity compatible Merkle tree of the given remote FD, from the
* offset, for the amount of requested size or until EOF.
*/
- byte[] readFsverityMerkleTree(int id, long offset, int size);
+ byte[] readFsverityMerkleTree(int fd, long offset, int size);
- /** Returns the fs-verity signature of the given file ID. */
- byte[] readFsveritySignature(int id);
+ /** Returns the fs-verity signature of the given remote FD. */
+ byte[] readFsveritySignature(int fd);
/**
- * Writes the buffer to the given file ID from the file's offset. Returns the number of bytes
+ * Writes the buffer to the given remote FD from the file's offset. Returns the number of bytes
* written.
*/
- int writeFile(int id, in byte[] buf, long offset);
+ int writeFile(int fd, in byte[] buf, long offset);
- /** Resizes the file backed by the given file ID to the new size. */
- void resize(int id, long size);
+ /** Resizes the file backed by the given remote FD to the new size. */
+ void resize(int fd, long size);
/** Returns the file size. */
- long getFileSize(int id);
+ long getFileSize(int fd);
/**
- * Create a file given the directory ID.
+ * Create a file given the remote directory FD.
*
* @param basename The file name to create. Must not contain directory separator.
- * @return file ID that represents the new created file.
+ * @return file A remote FD that represents the new created file.
*/
- int createFileInDirectory(int id, String basename);
+ int createFileInDirectory(int fd, String basename);
/**
- * Create a directory inside the given directory ID.
+ * Create a directory inside the given remote directory FD.
*
* @param basename The directory name to create. Must not contain directory separator.
- * @return file ID that represents the new created directory.
+ * @return file FD that represents the new created directory.
*/
int createDirectoryInDirectory(int id, String basename);
}
diff --git a/authfs/service/src/authfs.rs b/authfs/service/src/authfs.rs
index 6d87243..1b05749 100644
--- a/authfs/service/src/authfs.rs
+++ b/authfs/service/src/authfs.rs
@@ -132,11 +132,11 @@
// TODO(b/185178698): Many input files need to be signed and verified.
// or can we use debug cert for now, which is better than nothing?
args.push(OsString::from("--remote-ro-file-unverified"));
- args.push(OsString::from(format!("{}:{}", conf.fd, conf.fd)));
+ args.push(OsString::from(conf.fd.to_string()));
}
for conf in out_fds {
args.push(OsString::from("--remote-new-rw-file"));
- args.push(OsString::from(format!("{}:{}", conf.fd, conf.fd)));
+ args.push(OsString::from(conf.fd.to_string()));
}
if debuggable {
args.push(OsString::from("--debug"));
diff --git a/authfs/src/main.rs b/authfs/src/main.rs
index 0add77f..a5fe2c3 100644
--- a/authfs/src/main.rs
+++ b/authfs/src/main.rs
@@ -62,33 +62,33 @@
/// A read-only remote file with integrity check. Can be multiple.
///
- /// For example, `--remote-verified-file 5:10:/path/to/cert` tells the filesystem to associate
- /// entry 5 with a remote file 10, and need to be verified against the /path/to/cert.
+ /// For example, `--remote-ro-file 5:/path/to/cert` tells the filesystem to associate the
+ /// file $MOUNTPOINT/5 with a remote FD 5, and need to be verified against the /path/to/cert.
#[structopt(long, parse(try_from_str = parse_remote_ro_file_option))]
remote_ro_file: Vec<OptionRemoteRoFile>,
/// A read-only remote file without integrity check. Can be multiple.
///
- /// For example, `--remote-unverified-file 5:10` tells the filesystem to associate entry 5
- /// with a remote file 10.
- #[structopt(long, parse(try_from_str = parse_remote_ro_file_unverified_option))]
- remote_ro_file_unverified: Vec<OptionRemoteRoFileUnverified>,
+ /// For example, `--remote-ro-file-unverified 5` tells the filesystem to associate the file
+ /// $MOUNTPOINT/5 with a remote FD 5.
+ #[structopt(long)]
+ remote_ro_file_unverified: Vec<i32>,
/// A new read-writable remote file with integrity check. Can be multiple.
///
- /// For example, `--remote-new-verified-file 12:34` tells the filesystem to associate entry 12
- /// with a remote file 34.
- #[structopt(long, parse(try_from_str = parse_remote_new_rw_file_option))]
- remote_new_rw_file: Vec<OptionRemoteRwFile>,
+ /// For example, `--remote-new-rw-file 5` tells the filesystem to associate the file
+ /// $MOUNTPOINT/5 with a remote FD 5.
+ #[structopt(long)]
+ remote_new_rw_file: Vec<i32>,
/// A new directory that is assumed empty in the backing filesystem. New files created in this
/// directory are integrity-protected in the same way as --remote-new-verified-file. Can be
/// multiple.
///
- /// For example, `--remote-new-verified-dir 12:34` tells the filesystem to associate entry 12
- /// with a remote dir FD 34.
- #[structopt(long, parse(try_from_str = parse_remote_new_rw_dir_option))]
- remote_new_rw_dir: Vec<OptionRemoteRwDir>,
+ /// For example, `--remote-new-rw-dir 5` tells the filesystem to associate $MOUNTPOINT/5
+ /// with a remote dir FD 5.
+ #[structopt(long)]
+ remote_new_rw_dir: Vec<i32>,
/// Enable debugging features.
#[structopt(long)]
@@ -96,97 +96,40 @@
}
struct OptionRemoteRoFile {
- ino: Inode,
-
/// ID to refer to the remote file.
- remote_id: i32,
+ remote_fd: i32,
/// Certificate to verify the authenticity of the file's fs-verity signature.
/// TODO(170494765): Implement PKCS#7 signature verification.
_certificate_path: PathBuf,
}
-struct OptionRemoteRoFileUnverified {
- ino: Inode,
-
- /// ID to refer to the remote file.
- remote_id: i32,
-}
-
-struct OptionRemoteRwFile {
- ino: Inode,
-
- /// ID to refer to the remote file.
- remote_id: i32,
-}
-
-struct OptionRemoteRwDir {
- ino: Inode,
-
- /// ID to refer to the remote dir.
- remote_id: i32,
-}
-
fn parse_remote_ro_file_option(option: &str) -> Result<OptionRemoteRoFile> {
let strs: Vec<&str> = option.split(':').collect();
- if strs.len() != 3 {
+ if strs.len() != 2 {
bail!("Invalid option: {}", option);
}
Ok(OptionRemoteRoFile {
- ino: strs[0].parse::<Inode>()?,
- remote_id: strs[1].parse::<i32>()?,
- _certificate_path: PathBuf::from(strs[2]),
- })
-}
-
-fn parse_remote_ro_file_unverified_option(option: &str) -> Result<OptionRemoteRoFileUnverified> {
- let strs: Vec<&str> = option.split(':').collect();
- if strs.len() != 2 {
- bail!("Invalid option: {}", option);
- }
- Ok(OptionRemoteRoFileUnverified {
- ino: strs[0].parse::<Inode>()?,
- remote_id: strs[1].parse::<i32>()?,
- })
-}
-
-fn parse_remote_new_rw_file_option(option: &str) -> Result<OptionRemoteRwFile> {
- let strs: Vec<&str> = option.split(':').collect();
- if strs.len() != 2 {
- bail!("Invalid option: {}", option);
- }
- Ok(OptionRemoteRwFile {
- ino: strs[0].parse::<Inode>().unwrap(),
- remote_id: strs[1].parse::<i32>().unwrap(),
- })
-}
-
-fn parse_remote_new_rw_dir_option(option: &str) -> Result<OptionRemoteRwDir> {
- let strs: Vec<&str> = option.split(':').collect();
- if strs.len() != 2 {
- bail!("Invalid option: {}", option);
- }
- Ok(OptionRemoteRwDir {
- ino: strs[0].parse::<Inode>().unwrap(),
- remote_id: strs[1].parse::<i32>().unwrap(),
+ remote_fd: strs[0].parse::<i32>()?,
+ _certificate_path: PathBuf::from(strs[1]),
})
}
fn new_config_remote_verified_file(
service: file::VirtFdService,
- remote_id: i32,
+ remote_fd: i32,
file_size: u64,
) -> Result<FileConfig> {
- let signature = service.readFsveritySignature(remote_id).context("Failed to read signature")?;
+ let signature = service.readFsveritySignature(remote_fd).context("Failed to read signature")?;
let authenticator = FakeAuthenticator::always_succeed();
Ok(FileConfig::VerifiedReadonly {
reader: VerifiedFileReader::new(
&authenticator,
- RemoteFileReader::new(service.clone(), remote_id),
+ RemoteFileReader::new(service.clone(), remote_fd),
file_size,
signature,
- RemoteMerkleTreeReader::new(service.clone(), remote_id),
+ RemoteMerkleTreeReader::new(service.clone(), remote_fd),
)?,
file_size,
})
@@ -194,26 +137,26 @@
fn new_config_remote_unverified_file(
service: file::VirtFdService,
- remote_id: i32,
+ remote_fd: i32,
file_size: u64,
) -> Result<FileConfig> {
- let reader = RemoteFileReader::new(service, remote_id);
+ let reader = RemoteFileReader::new(service, remote_fd);
Ok(FileConfig::UnverifiedReadonly { reader, file_size })
}
fn new_config_remote_new_verified_file(
service: file::VirtFdService,
- remote_id: i32,
+ remote_fd: i32,
) -> Result<FileConfig> {
- let remote_file = RemoteFileEditor::new(service, remote_id);
+ let remote_file = RemoteFileEditor::new(service, remote_fd);
Ok(FileConfig::VerifiedNew { editor: VerifiedFileEditor::new(remote_file) })
}
fn new_config_remote_new_verified_dir(
service: file::VirtFdService,
- remote_id: i32,
+ remote_fd: i32,
) -> Result<FileConfig> {
- let dir = RemoteDirEditor::new(service, remote_id);
+ let dir = RemoteDirEditor::new(service, remote_fd);
Ok(FileConfig::VerifiedNewDirectory { dir })
}
@@ -224,37 +167,40 @@
for config in &args.remote_ro_file {
file_pool.insert(
- config.ino,
+ config.remote_fd.try_into()?,
new_config_remote_verified_file(
service.clone(),
- config.remote_id,
- service.getFileSize(config.remote_id)?.try_into()?,
+ config.remote_fd,
+ service.getFileSize(config.remote_fd)?.try_into()?,
)?,
);
}
- for config in &args.remote_ro_file_unverified {
+ for remote_fd in &args.remote_ro_file_unverified {
+ let remote_fd = *remote_fd;
file_pool.insert(
- config.ino,
+ remote_fd.try_into()?,
new_config_remote_unverified_file(
service.clone(),
- config.remote_id,
- service.getFileSize(config.remote_id)?.try_into()?,
+ remote_fd,
+ service.getFileSize(remote_fd)?.try_into()?,
)?,
);
}
- for config in &args.remote_new_rw_file {
+ for remote_fd in &args.remote_new_rw_file {
+ let remote_fd = *remote_fd;
file_pool.insert(
- config.ino,
- new_config_remote_new_verified_file(service.clone(), config.remote_id)?,
+ remote_fd.try_into()?,
+ new_config_remote_new_verified_file(service.clone(), remote_fd)?,
);
}
- for config in &args.remote_new_rw_dir {
+ for remote_fd in &args.remote_new_rw_dir {
+ let remote_fd = *remote_fd;
file_pool.insert(
- config.ino,
- new_config_remote_new_verified_dir(service.clone(), config.remote_id)?,
+ remote_fd.try_into()?,
+ new_config_remote_new_verified_dir(service.clone(), remote_fd)?,
);
}
diff --git a/authfs/tests/java/src/com/android/fs/AuthFsHostTest.java b/authfs/tests/java/src/com/android/fs/AuthFsHostTest.java
index 6e67014..8a13ef3 100644
--- a/authfs/tests/java/src/com/android/fs/AuthFsHostTest.java
+++ b/authfs/tests/java/src/com/android/fs/AuthFsHostTest.java
@@ -166,18 +166,18 @@
"--ro-fds 3:4:5 --ro-fds 6");
runAuthFsOnMicrodroid(
- "--remote-ro-file-unverified 10:6 --remote-ro-file 11:3:cert.der --cid "
+ "--remote-ro-file-unverified 6 --remote-ro-file 3:cert.der --cid "
+ VMADDR_CID_HOST);
// Action
- String actualHashUnverified4m = computeFileHashOnMicrodroid(MOUNT_DIR + "/10");
- String actualHash4m = computeFileHashOnMicrodroid(MOUNT_DIR + "/11");
+ String actualHashUnverified4m = computeFileHashOnMicrodroid(MOUNT_DIR + "/6");
+ String actualHash4m = computeFileHashOnMicrodroid(MOUNT_DIR + "/3");
// Verify
String expectedHash4m = computeFileHashOnAndroid(TEST_DIR + "/input.4m");
- assertEquals("Inconsistent hash from /authfs/10: ", expectedHash4m, actualHashUnverified4m);
- assertEquals("Inconsistent hash from /authfs/11: ", expectedHash4m, actualHash4m);
+ assertEquals("Inconsistent hash from /authfs/6: ", expectedHash4m, actualHashUnverified4m);
+ assertEquals("Inconsistent hash from /authfs/3: ", expectedHash4m, actualHash4m);
}
// Separate the test from the above simply because exec in shell does not allow open too many
@@ -191,19 +191,18 @@
+ " --open-ro 8:input.4k1.fsv_sig",
"--ro-fds 3:4:5 --ro-fds 6:7:8");
runAuthFsOnMicrodroid(
- "--remote-ro-file 10:3:cert.der --remote-ro-file 11:6:cert.der --cid "
- + VMADDR_CID_HOST);
+ "--remote-ro-file 3:cert.der --remote-ro-file 6:cert.der --cid " + VMADDR_CID_HOST);
// Action
- String actualHash4k = computeFileHashOnMicrodroid(MOUNT_DIR + "/10");
- String actualHash4k1 = computeFileHashOnMicrodroid(MOUNT_DIR + "/11");
+ String actualHash4k = computeFileHashOnMicrodroid(MOUNT_DIR + "/3");
+ String actualHash4k1 = computeFileHashOnMicrodroid(MOUNT_DIR + "/6");
// Verify
String expectedHash4k = computeFileHashOnAndroid(TEST_DIR + "/input.4k");
String expectedHash4k1 = computeFileHashOnAndroid(TEST_DIR + "/input.4k1");
- assertEquals("Inconsistent hash from /authfs/10: ", expectedHash4k, actualHash4k);
- assertEquals("Inconsistent hash from /authfs/11: ", expectedHash4k1, actualHash4k1);
+ assertEquals("Inconsistent hash from /authfs/3: ", expectedHash4k, actualHash4k);
+ assertEquals("Inconsistent hash from /authfs/6: ", expectedHash4k1, actualHash4k1);
}
@Test
@@ -213,21 +212,21 @@
"--open-ro 3:input.4m --open-ro 4:input.4m.merkle_dump.bad "
+ "--open-ro 5:input.4m.fsv_sig",
"--ro-fds 3:4:5");
- runAuthFsOnMicrodroid("--remote-ro-file 10:3:cert.der --cid " + VMADDR_CID_HOST);
+ runAuthFsOnMicrodroid("--remote-ro-file 3:cert.der --cid " + VMADDR_CID_HOST);
// Verify
- assertFalse(copyFileOnMicrodroid(MOUNT_DIR + "/10", "/dev/null"));
+ assertFalse(copyFileOnMicrodroid(MOUNT_DIR + "/3", "/dev/null"));
}
@Test
public void testWriteThroughCorrectly() throws Exception {
// Setup
runFdServerOnAndroid("--open-rw 3:" + TEST_OUTPUT_DIR + "/out.file", "--rw-fds 3");
- runAuthFsOnMicrodroid("--remote-new-rw-file 20:3 --cid " + VMADDR_CID_HOST);
+ runAuthFsOnMicrodroid("--remote-new-rw-file 3 --cid " + VMADDR_CID_HOST);
// Action
String srcPath = "/system/bin/linker64";
- String destPath = MOUNT_DIR + "/20";
+ String destPath = MOUNT_DIR + "/3";
String backendPath = TEST_OUTPUT_DIR + "/out.file";
assertTrue(copyFileOnMicrodroid(srcPath, destPath));
@@ -240,10 +239,10 @@
public void testWriteFailedIfDetectsTampering() throws Exception {
// Setup
runFdServerOnAndroid("--open-rw 3:" + TEST_OUTPUT_DIR + "/out.file", "--rw-fds 3");
- runAuthFsOnMicrodroid("--remote-new-rw-file 20:3 --cid " + VMADDR_CID_HOST);
+ runAuthFsOnMicrodroid("--remote-new-rw-file 3 --cid " + VMADDR_CID_HOST);
String srcPath = "/system/bin/linker64";
- String destPath = MOUNT_DIR + "/20";
+ String destPath = MOUNT_DIR + "/3";
String backendPath = TEST_OUTPUT_DIR + "/out.file";
assertTrue(copyFileOnMicrodroid(srcPath, destPath));
@@ -275,8 +274,8 @@
public void testFileResize() throws Exception {
// Setup
runFdServerOnAndroid("--open-rw 3:" + TEST_OUTPUT_DIR + "/out.file", "--rw-fds 3");
- runAuthFsOnMicrodroid("--remote-new-rw-file 20:3 --cid " + VMADDR_CID_HOST);
- String outputPath = MOUNT_DIR + "/20";
+ runAuthFsOnMicrodroid("--remote-new-rw-file 3 --cid " + VMADDR_CID_HOST);
+ String outputPath = MOUNT_DIR + "/3";
String backendPath = TEST_OUTPUT_DIR + "/out.file";
// Action & Verify
@@ -306,10 +305,10 @@
public void testOutputDirectory_WriteNewFiles() throws Exception {
// Setup
String androidOutputDir = TEST_OUTPUT_DIR + "/dir";
- String authfsOutputDir = MOUNT_DIR + "/20";
+ String authfsOutputDir = MOUNT_DIR + "/3";
sAndroid.run("mkdir " + androidOutputDir);
runFdServerOnAndroid("--open-dir 3:" + androidOutputDir, "--rw-dirs 3");
- runAuthFsOnMicrodroid("--remote-new-rw-dir 20:3 --cid " + VMADDR_CID_HOST);
+ runAuthFsOnMicrodroid("--remote-new-rw-dir 3 --cid " + VMADDR_CID_HOST);
// Action & Verify
// Can create a new file to write.
@@ -335,10 +334,10 @@
public void testOutputDirectory_MkdirAndWriteFile() throws Exception {
// Setup
String androidOutputDir = TEST_OUTPUT_DIR + "/dir";
- String authfsOutputDir = MOUNT_DIR + "/20";
+ String authfsOutputDir = MOUNT_DIR + "/3";
sAndroid.run("mkdir " + androidOutputDir);
runFdServerOnAndroid("--open-dir 3:" + androidOutputDir, "--rw-dirs 3");
- runAuthFsOnMicrodroid("--remote-new-rw-dir 20:3 --cid " + VMADDR_CID_HOST);
+ runAuthFsOnMicrodroid("--remote-new-rw-dir 3 --cid " + VMADDR_CID_HOST);
// Action
// Can create nested directories and can create a file in one.
@@ -369,10 +368,10 @@
public void testOutputDirectory_CreateAndTruncateExistingFile() throws Exception {
// Setup
String androidOutputDir = TEST_OUTPUT_DIR + "/dir";
- String authfsOutputDir = MOUNT_DIR + "/20";
+ String authfsOutputDir = MOUNT_DIR + "/3";
sAndroid.run("mkdir " + androidOutputDir);
runFdServerOnAndroid("--open-dir 3:" + androidOutputDir, "--rw-dirs 3");
- runAuthFsOnMicrodroid("--remote-new-rw-dir 20:3 --cid " + VMADDR_CID_HOST);
+ runAuthFsOnMicrodroid("--remote-new-rw-dir 3 --cid " + VMADDR_CID_HOST);
// Action & Verify
runOnMicrodroid("echo -n foo > " + authfsOutputDir + "/file");
@@ -390,10 +389,10 @@
public void testOutputDirectory_CannotRecreateDirectoryIfNameExists() throws Exception {
// Setup
String androidOutputDir = TEST_OUTPUT_DIR + "/dir";
- String authfsOutputDir = MOUNT_DIR + "/20";
+ String authfsOutputDir = MOUNT_DIR + "/3";
sAndroid.run("mkdir " + androidOutputDir);
runFdServerOnAndroid("--open-dir 3:" + androidOutputDir, "--rw-dirs 3");
- runAuthFsOnMicrodroid("--remote-new-rw-dir 20:3 --cid " + VMADDR_CID_HOST);
+ runAuthFsOnMicrodroid("--remote-new-rw-dir 3 --cid " + VMADDR_CID_HOST);
runOnMicrodroid("touch " + authfsOutputDir + "/some_file");
runOnMicrodroid("mkdir " + authfsOutputDir + "/some_dir");