authfs: Support binder-backed file source

This change adds remote file support to authfs. This allows a process to
read a remote file through a local path with transparent fs-verity
verification.

This is supposed to work across VM boundary, but before the remote
binder is ready, this change uses local binder.

Test: Shell #1
      $ adb shell 'exec
          9</system/bin/sh
          8</data/local/tmp/input.4m
          7</data/local/tmp/input.4m.merkle_dump
          6</data/local/tmp/input.4m.fsv_sig

          fd_server
          --ro-fds 9
          --ro-fds 8:7:6'`
      Shell #2
      $ adb push tools/device-test.sh /data/local/tmp/ && \
        adb shell /data/local/tmp/device-test.sh

Change-Id: Ia69fae548b83ff3ba572f4a496a7cbcca518cbef
diff --git a/authfs/src/fusefs.rs b/authfs/src/fusefs.rs
index 484aad4..0dfd0af 100644
--- a/authfs/src/fusefs.rs
+++ b/authfs/src/fusefs.rs
@@ -32,6 +32,7 @@
 use crate::common::{divide_roundup, COMMON_PAGE_SIZE};
 use crate::fsverity::FsverityChunkedFileReader;
 use crate::reader::{ChunkedFileReader, ReadOnlyDataByChunk};
+use crate::remote_file::{RemoteChunkedFileReader, RemoteFsverityMerkleTreeReader};
 
 // 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;
@@ -41,6 +42,9 @@
 pub type Inode = u64;
 type Handle = u64;
 
+type RemoteFsverityChunkedFileReader =
+    FsverityChunkedFileReader<RemoteChunkedFileReader, RemoteFsverityMerkleTreeReader>;
+
 // A debug only type where everything are stored as local files.
 type FileBackedFsverityChunkedFileReader =
     FsverityChunkedFileReader<ChunkedFileReader, ChunkedFileReader>;
@@ -48,6 +52,8 @@
 pub enum FileConfig {
     LocalVerifiedFile(FileBackedFsverityChunkedFileReader, u64),
     LocalUnverifiedFile(ChunkedFileReader, u64),
+    RemoteVerifiedFile(RemoteFsverityChunkedFileReader, u64),
+    RemoteUnverifiedFile(RemoteChunkedFileReader, u64),
 }
 
 struct AuthFs {
@@ -204,7 +210,9 @@
         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)?,
+            | FileConfig::LocalUnverifiedFile(_, file_size)
+            | FileConfig::RemoteUnverifiedFile(_, file_size)
+            | FileConfig::RemoteVerifiedFile(_, file_size) => create_stat(inode, *file_size)?,
         };
         Ok(Entry {
             inode,
@@ -224,7 +232,9 @@
         Ok((
             match self.get_file_config(&inode)? {
                 FileConfig::LocalVerifiedFile(_, file_size)
-                | FileConfig::LocalUnverifiedFile(_, file_size) => create_stat(inode, *file_size)?,
+                | FileConfig::LocalUnverifiedFile(_, file_size)
+                | FileConfig::RemoteUnverifiedFile(_, file_size)
+                | FileConfig::RemoteVerifiedFile(_, file_size) => create_stat(inode, *file_size)?,
             },
             DEFAULT_METADATA_TIMEOUT,
         ))
@@ -239,13 +249,13 @@
         // 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(_, _) => {
+            FileConfig::LocalVerifiedFile(_, _) | FileConfig::RemoteVerifiedFile(_, _) => {
                 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(_, _) => {
+            FileConfig::LocalUnverifiedFile(_, _) | FileConfig::RemoteUnverifiedFile(_, _) => {
                 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
@@ -273,6 +283,12 @@
             FileConfig::LocalUnverifiedFile(file, file_size) => {
                 read_chunks(w, file, *file_size, offset, size)
             }
+            FileConfig::RemoteVerifiedFile(file, file_size) => {
+                read_chunks(w, file, *file_size, offset, size)
+            }
+            FileConfig::RemoteUnverifiedFile(file, file_size) => {
+                read_chunks(w, file, *file_size, offset, size)
+            }
         }
     }
 }