Deprecate local file support in authfs

Local file was supported during early development, but it's not actually
used.

The names in FileConfig enum are renamed to make linter happy (which
is reasonable since all files are now remote).

Bug: 203251769
Test: atest AuthFsHostTest authfs_device_test_src_lib
Change-Id: I9f1f800453695c84fe4fc15a89b5a434fdaa0331
diff --git a/authfs/src/file.rs b/authfs/src/file.rs
index 947b59f..404e3a5 100644
--- a/authfs/src/file.rs
+++ b/authfs/src/file.rs
@@ -1,7 +1,5 @@
-mod local_file;
 mod remote_file;
 
-pub use local_file::LocalFileReader;
 pub use remote_file::{RemoteFileEditor, RemoteFileReader, RemoteMerkleTreeReader};
 
 use binder::unstable_api::{new_spibinder, AIBinder};
diff --git a/authfs/src/file/local_file.rs b/authfs/src/file/local_file.rs
deleted file mode 100644
index 13c954f..0000000
--- a/authfs/src/file/local_file.rs
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * 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 std::cmp::min;
-use std::fs::File;
-use std::io;
-use std::os::unix::fs::FileExt;
-
-use super::{ChunkBuffer, ReadByChunk};
-use crate::common::CHUNK_SIZE;
-
-/// A read-only file that can be read by chunks.
-pub struct LocalFileReader {
-    file: File,
-    size: u64,
-}
-
-impl LocalFileReader {
-    /// Creates a `LocalFileReader` to read from for the specified `path`.
-    pub fn new(file: File) -> io::Result<LocalFileReader> {
-        let size = file.metadata()?.len();
-        Ok(LocalFileReader { file, size })
-    }
-
-    pub fn len(&self) -> u64 {
-        self.size
-    }
-}
-
-impl ReadByChunk for LocalFileReader {
-    fn read_chunk(&self, chunk_index: u64, buf: &mut ChunkBuffer) -> io::Result<usize> {
-        let start = chunk_index * CHUNK_SIZE;
-        if start >= self.size {
-            return Ok(0);
-        }
-        let end = min(self.size, start + CHUNK_SIZE);
-        let read_size = (end - start) as usize;
-        debug_assert!(read_size <= buf.len());
-        self.file.read_exact_at(&mut buf[..read_size], start)?;
-        Ok(read_size)
-    }
-}
-
-#[cfg(test)]
-mod tests {
-    use super::*;
-    use std::env::temp_dir;
-
-    #[test]
-    fn test_read_4k_file() -> io::Result<()> {
-        let file_reader = LocalFileReader::new(File::open("testdata/input.4k")?)?;
-        let mut buf = [0u8; 4096];
-        let size = file_reader.read_chunk(0, &mut buf)?;
-        assert_eq!(size, buf.len());
-        Ok(())
-    }
-
-    #[test]
-    fn test_read_4k1_file() -> io::Result<()> {
-        let file_reader = LocalFileReader::new(File::open("testdata/input.4k1")?)?;
-        let mut buf = [0u8; 4096];
-        let size = file_reader.read_chunk(0, &mut buf)?;
-        assert_eq!(size, buf.len());
-        let size = file_reader.read_chunk(1, &mut buf)?;
-        assert_eq!(size, 1);
-        Ok(())
-    }
-
-    #[test]
-    fn test_read_4m_file() -> io::Result<()> {
-        let file_reader = LocalFileReader::new(File::open("testdata/input.4m")?)?;
-        for index in 0..file_reader.len() / 4096 {
-            let mut buf = [0u8; 4096];
-            let size = file_reader.read_chunk(index, &mut buf)?;
-            assert_eq!(size, buf.len());
-        }
-        Ok(())
-    }
-
-    #[test]
-    fn test_read_beyond_file_size() -> io::Result<()> {
-        let file_reader = LocalFileReader::new(File::open("testdata/input.4k").unwrap()).unwrap();
-        let mut buf = [0u8; 4096];
-        let size = file_reader.read_chunk(1u64, &mut buf)?;
-        assert_eq!(size, 0);
-        Ok(())
-    }
-
-    #[test]
-    fn test_read_empty_file() -> io::Result<()> {
-        let mut temp_file = temp_dir();
-        temp_file.push("authfs_test_empty_file");
-        let file_reader = LocalFileReader::new(File::create(temp_file).unwrap()).unwrap();
-        let mut buf = [0u8; 4096];
-        let size = file_reader.read_chunk(0, &mut buf)?;
-        assert_eq!(size, 0);
-        Ok(())
-    }
-}
diff --git a/authfs/src/fsverity/verifier.rs b/authfs/src/fsverity/verifier.rs
index 1f21b13..4a18c6a 100644
--- a/authfs/src/fsverity/verifier.rs
+++ b/authfs/src/fsverity/verifier.rs
@@ -173,10 +173,42 @@
 mod tests {
     use super::*;
     use crate::auth::FakeAuthenticator;
-    use crate::file::{LocalFileReader, ReadByChunk};
+    use crate::file::ReadByChunk;
     use anyhow::Result;
+    use std::cmp::min;
     use std::fs::{self, File};
     use std::io::Read;
+    use std::os::unix::fs::FileExt;
+
+    struct LocalFileReader {
+        file: File,
+        size: u64,
+    }
+
+    impl LocalFileReader {
+        fn new(file: File) -> io::Result<LocalFileReader> {
+            let size = file.metadata()?.len();
+            Ok(LocalFileReader { file, size })
+        }
+
+        fn len(&self) -> u64 {
+            self.size
+        }
+    }
+
+    impl ReadByChunk for LocalFileReader {
+        fn read_chunk(&self, chunk_index: u64, buf: &mut ChunkBuffer) -> io::Result<usize> {
+            let start = chunk_index * CHUNK_SIZE;
+            if start >= self.size {
+                return Ok(0);
+            }
+            let end = min(self.size, start + CHUNK_SIZE);
+            let read_size = (end - start) as usize;
+            debug_assert!(read_size <= buf.len());
+            self.file.read_exact_at(&mut buf[..read_size], start)?;
+            Ok(read_size)
+        }
+    }
 
     type LocalVerifiedFileReader = VerifiedFileReader<LocalFileReader, LocalFileReader>;
 
diff --git a/authfs/src/fusefs.rs b/authfs/src/fusefs.rs
index 6bdb498..d54b5be 100644
--- a/authfs/src/fusefs.rs
+++ b/authfs/src/fusefs.rs
@@ -35,8 +35,7 @@
 
 use crate::common::{divide_roundup, ChunkedSizeIter, CHUNK_SIZE};
 use crate::file::{
-    LocalFileReader, RandomWrite, ReadByChunk, RemoteFileEditor, RemoteFileReader,
-    RemoteMerkleTreeReader,
+    RandomWrite, ReadByChunk, RemoteFileEditor, RemoteFileReader, RemoteMerkleTreeReader,
 };
 use crate::fsverity::{VerifiedFileEditor, VerifiedFileReader};
 
@@ -48,24 +47,16 @@
 /// `FileConfig` defines the file type supported by AuthFS.
 pub enum FileConfig {
     /// A file type that is verified against fs-verity signature (thus read-only). The file is
-    /// backed by a local file. Debug only.
-    LocalVerifiedReadonly {
-        reader: VerifiedFileReader<LocalFileReader, LocalFileReader>,
-        file_size: u64,
-    },
-    /// A file type that is a read-only passthrough from a local file. Debug only.
-    LocalUnverifiedReadonly { reader: LocalFileReader, file_size: u64 },
-    /// A file type that is verified against fs-verity signature (thus read-only). The file is
     /// served from a remote server.
-    RemoteVerifiedReadonly {
+    VerifiedReadonly {
         reader: VerifiedFileReader<RemoteFileReader, RemoteMerkleTreeReader>,
         file_size: u64,
     },
     /// A file type that is a read-only passthrough from a file on a remote serrver.
-    RemoteUnverifiedReadonly { reader: RemoteFileReader, file_size: u64 },
+    UnverifiedReadonly { reader: RemoteFileReader, file_size: u64 },
     /// A file type that is initially empty, and the content is stored on a remote server. File
     /// integrity is guaranteed with private Merkle tree.
-    RemoteVerifiedNew { editor: VerifiedFileEditor<RemoteFileEditor> },
+    VerifiedNew { editor: VerifiedFileEditor<RemoteFileEditor> },
 }
 
 struct AuthFs {
@@ -207,13 +198,11 @@
         // 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::LocalVerifiedReadonly { file_size, .. }
-            | FileConfig::LocalUnverifiedReadonly { file_size, .. }
-            | FileConfig::RemoteUnverifiedReadonly { file_size, .. }
-            | FileConfig::RemoteVerifiedReadonly { file_size, .. } => {
+            FileConfig::UnverifiedReadonly { file_size, .. }
+            | FileConfig::VerifiedReadonly { file_size, .. } => {
                 create_stat(inode, *file_size, FileMode::ReadOnly)?
             }
-            FileConfig::RemoteVerifiedNew { editor } => {
+            FileConfig::VerifiedNew { editor } => {
                 create_stat(inode, editor.size(), FileMode::ReadWrite)?
             }
         };
@@ -234,13 +223,11 @@
     ) -> io::Result<(libc::stat64, Duration)> {
         Ok((
             match self.get_file_config(&inode)? {
-                FileConfig::LocalVerifiedReadonly { file_size, .. }
-                | FileConfig::LocalUnverifiedReadonly { file_size, .. }
-                | FileConfig::RemoteUnverifiedReadonly { file_size, .. }
-                | FileConfig::RemoteVerifiedReadonly { file_size, .. } => {
+                FileConfig::UnverifiedReadonly { file_size, .. }
+                | FileConfig::VerifiedReadonly { file_size, .. } => {
                     create_stat(inode, *file_size, FileMode::ReadOnly)?
                 }
-                FileConfig::RemoteVerifiedNew { editor } => {
+                FileConfig::VerifiedNew { editor } => {
                     create_stat(inode, editor.size(), FileMode::ReadWrite)?
                 }
             },
@@ -257,13 +244,10 @@
         // 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::LocalVerifiedReadonly { .. }
-            | FileConfig::LocalUnverifiedReadonly { .. }
-            | FileConfig::RemoteVerifiedReadonly { .. }
-            | FileConfig::RemoteUnverifiedReadonly { .. } => {
+            FileConfig::VerifiedReadonly { .. } | FileConfig::UnverifiedReadonly { .. } => {
                 check_access_mode(flags, libc::O_RDONLY)?;
             }
-            FileConfig::RemoteVerifiedNew { .. } => {
+            FileConfig::VerifiedNew { .. } => {
                 // No need to check access modes since all the modes are allowed to the
                 // read-writable file.
             }
@@ -285,19 +269,13 @@
         _flags: u32,
     ) -> io::Result<usize> {
         match self.get_file_config(&inode)? {
-            FileConfig::LocalVerifiedReadonly { reader, file_size } => {
+            FileConfig::VerifiedReadonly { reader, file_size } => {
                 read_chunks(w, reader, *file_size, offset, size)
             }
-            FileConfig::LocalUnverifiedReadonly { reader, file_size } => {
+            FileConfig::UnverifiedReadonly { reader, file_size } => {
                 read_chunks(w, reader, *file_size, offset, size)
             }
-            FileConfig::RemoteVerifiedReadonly { reader, file_size } => {
-                read_chunks(w, reader, *file_size, offset, size)
-            }
-            FileConfig::RemoteUnverifiedReadonly { reader, file_size } => {
-                read_chunks(w, reader, *file_size, offset, size)
-            }
-            FileConfig::RemoteVerifiedNew { editor } => {
+            FileConfig::VerifiedNew { editor } => {
                 // Note that with FsOptions::WRITEBACK_CACHE, it's possible for the kernel to
                 // request a read even if the file is open with O_WRONLY.
                 read_chunks(w, editor, editor.size(), offset, size)
@@ -318,7 +296,7 @@
         _flags: u32,
     ) -> io::Result<usize> {
         match self.get_file_config(&inode)? {
-            FileConfig::RemoteVerifiedNew { editor } => {
+            FileConfig::VerifiedNew { editor } => {
                 let mut buf = vec![0; size as usize];
                 r.read_exact(&mut buf)?;
                 editor.write_at(&buf, offset)
@@ -336,7 +314,7 @@
         valid: SetattrValid,
     ) -> io::Result<(libc::stat64, Duration)> {
         match self.get_file_config(&inode)? {
-            FileConfig::RemoteVerifiedNew { editor } => {
+            FileConfig::VerifiedNew { editor } => {
                 // Initialize the default stat.
                 let mut new_attr = create_stat(inode, editor.size(), FileMode::ReadWrite)?;
                 // `valid` indicates what fields in `attr` are valid. Update to return correctly.
@@ -383,7 +361,7 @@
         size: u32,
     ) -> io::Result<GetxattrReply> {
         match self.get_file_config(&inode)? {
-            FileConfig::RemoteVerifiedNew { editor } => {
+            FileConfig::VerifiedNew { editor } => {
                 // FUSE ioctl is limited, thus we can't implement fs-verity ioctls without a kernel
                 // change (see b/196635431). Until it's possible, use xattr to expose what we need
                 // as an authfs specific API.
diff --git a/authfs/src/main.rs b/authfs/src/main.rs
index ecb0e68..a6956e2 100644
--- a/authfs/src/main.rs
+++ b/authfs/src/main.rs
@@ -22,18 +22,16 @@
 //! 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.
+//! source (e.g. 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, Context, Result};
 use log::error;
 use std::collections::BTreeMap;
 use std::convert::TryInto;
-use std::fs::File;
-use std::io::Read;
-use std::path::{Path, PathBuf};
+use std::path::PathBuf;
 use structopt::StructOpt;
 
 mod auth;
@@ -44,7 +42,7 @@
 mod fusefs;
 
 use auth::FakeAuthenticator;
-use file::{LocalFileReader, RemoteFileEditor, RemoteFileReader, RemoteMerkleTreeReader};
+use file::{RemoteFileEditor, RemoteFileReader, RemoteMerkleTreeReader};
 use fsverity::{VerifiedFileEditor, VerifiedFileReader};
 use fusefs::{FileConfig, Inode};
 
@@ -83,27 +81,11 @@
     #[structopt(long, parse(try_from_str = parse_remote_new_rw_file_option))]
     remote_new_rw_file: Vec<OptionRemoteRwFile>,
 
-    /// Debug only. A read-only local file with integrity check. Can be multiple.
-    #[structopt(long, parse(try_from_str = parse_local_file_ro_option))]
-    local_ro_file: Vec<OptionLocalFileRo>,
-
-    /// Debug only. A read-only local file without integrity check. Can be multiple.
-    #[structopt(long, parse(try_from_str = parse_local_ro_file_unverified_ro_option))]
-    local_ro_file_unverified: Vec<OptionLocalRoFileUnverified>,
-
     /// Enable debugging features.
     #[structopt(long)]
     debug: bool,
 }
 
-impl Args {
-    fn has_remote_files(&self) -> bool {
-        !self.remote_ro_file.is_empty()
-            || !self.remote_ro_file_unverified.is_empty()
-            || !self.remote_new_rw_file.is_empty()
-    }
-}
-
 struct OptionRemoteRoFile {
     ino: Inode,
 
@@ -129,30 +111,6 @@
     remote_id: i32,
 }
 
-struct OptionLocalFileRo {
-    ino: Inode,
-
-    /// Local path of the backing file.
-    file_path: PathBuf,
-
-    /// Local path of the backing file's fs-verity Merkle tree dump.
-    merkle_tree_dump_path: PathBuf,
-
-    /// Local path of fs-verity signature for the backing file.
-    signature_path: PathBuf,
-
-    /// Certificate to verify the authenticity of the file's fs-verity signature.
-    /// TODO(170494765): Implement PKCS#7 signature verification.
-    _certificate_path: PathBuf,
-}
-
-struct OptionLocalRoFileUnverified {
-    ino: Inode,
-
-    /// Local path of the backing file.
-    file_path: PathBuf,
-}
-
 fn parse_remote_ro_file_option(option: &str) -> Result<OptionRemoteRoFile> {
     let strs: Vec<&str> = option.split(':').collect();
     if strs.len() != 3 {
@@ -187,31 +145,6 @@
     })
 }
 
-fn parse_local_file_ro_option(option: &str) -> Result<OptionLocalFileRo> {
-    let strs: Vec<&str> = option.split(':').collect();
-    if strs.len() != 5 {
-        bail!("Invalid option: {}", option);
-    }
-    Ok(OptionLocalFileRo {
-        ino: strs[0].parse::<Inode>()?,
-        file_path: PathBuf::from(strs[1]),
-        merkle_tree_dump_path: PathBuf::from(strs[2]),
-        signature_path: PathBuf::from(strs[3]),
-        _certificate_path: PathBuf::from(strs[4]),
-    })
-}
-
-fn parse_local_ro_file_unverified_ro_option(option: &str) -> Result<OptionLocalRoFileUnverified> {
-    let strs: Vec<&str> = option.split(':').collect();
-    if strs.len() != 2 {
-        bail!("Invalid option: {}", option);
-    }
-    Ok(OptionLocalRoFileUnverified {
-        ino: strs[0].parse::<Inode>()?,
-        file_path: PathBuf::from(strs[1]),
-    })
-}
-
 fn new_config_remote_verified_file(
     service: file::VirtFdService,
     remote_id: i32,
@@ -220,7 +153,7 @@
     let signature = service.readFsveritySignature(remote_id).context("Failed to read signature")?;
 
     let authenticator = FakeAuthenticator::always_succeed();
-    Ok(FileConfig::RemoteVerifiedReadonly {
+    Ok(FileConfig::VerifiedReadonly {
         reader: VerifiedFileReader::new(
             &authenticator,
             RemoteFileReader::new(service.clone(), remote_id),
@@ -238,30 +171,7 @@
     file_size: u64,
 ) -> Result<FileConfig> {
     let reader = RemoteFileReader::new(service, remote_id);
-    Ok(FileConfig::RemoteUnverifiedReadonly { reader, file_size })
-}
-
-fn new_config_local_ro_file(
-    protected_file: &Path,
-    merkle_tree_dump: &Path,
-    signature: &Path,
-) -> Result<FileConfig> {
-    let file = File::open(&protected_file)?;
-    let file_size = file.metadata()?.len();
-    let file_reader = LocalFileReader::new(file)?;
-    let merkle_tree_reader = LocalFileReader::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 reader =
-        VerifiedFileReader::new(&authenticator, file_reader, file_size, sig, merkle_tree_reader)?;
-    Ok(FileConfig::LocalVerifiedReadonly { reader, file_size })
-}
-
-fn new_config_local_ro_file_unverified(file_path: &Path) -> Result<FileConfig> {
-    let reader = LocalFileReader::new(File::open(file_path)?)?;
-    let file_size = reader.len();
-    Ok(FileConfig::LocalUnverifiedReadonly { reader, file_size })
+    Ok(FileConfig::UnverifiedReadonly { reader, file_size })
 }
 
 fn new_config_remote_new_verified_file(
@@ -269,58 +179,41 @@
     remote_id: i32,
 ) -> Result<FileConfig> {
     let remote_file = RemoteFileEditor::new(service, remote_id);
-    Ok(FileConfig::RemoteVerifiedNew { editor: VerifiedFileEditor::new(remote_file) })
+    Ok(FileConfig::VerifiedNew { editor: VerifiedFileEditor::new(remote_file) })
 }
 
 fn prepare_file_pool(args: &Args) -> Result<BTreeMap<Inode, FileConfig>> {
     let mut file_pool = BTreeMap::new();
 
-    if args.has_remote_files() {
-        let service = file::get_rpc_binder_service(args.cid)?;
+    let service = file::get_rpc_binder_service(args.cid)?;
 
-        for config in &args.remote_ro_file {
-            file_pool.insert(
-                config.ino,
-                new_config_remote_verified_file(
-                    service.clone(),
-                    config.remote_id,
-                    service.getFileSize(config.remote_id)?.try_into()?,
-                )?,
-            );
-        }
-
-        for config in &args.remote_ro_file_unverified {
-            file_pool.insert(
-                config.ino,
-                new_config_remote_unverified_file(
-                    service.clone(),
-                    config.remote_id,
-                    service.getFileSize(config.remote_id)?.try_into()?,
-                )?,
-            );
-        }
-
-        for config in &args.remote_new_rw_file {
-            file_pool.insert(
-                config.ino,
-                new_config_remote_new_verified_file(service.clone(), config.remote_id)?,
-            );
-        }
-    }
-
-    for config in &args.local_ro_file {
+    for config in &args.remote_ro_file {
         file_pool.insert(
             config.ino,
-            new_config_local_ro_file(
-                &config.file_path,
-                &config.merkle_tree_dump_path,
-                &config.signature_path,
+            new_config_remote_verified_file(
+                service.clone(),
+                config.remote_id,
+                service.getFileSize(config.remote_id)?.try_into()?,
             )?,
         );
     }
 
-    for config in &args.local_ro_file_unverified {
-        file_pool.insert(config.ino, new_config_local_ro_file_unverified(&config.file_path)?);
+    for config in &args.remote_ro_file_unverified {
+        file_pool.insert(
+            config.ino,
+            new_config_remote_unverified_file(
+                service.clone(),
+                config.remote_id,
+                service.getFileSize(config.remote_id)?.try_into()?,
+            )?,
+        );
+    }
+
+    for config in &args.remote_new_rw_file {
+        file_pool.insert(
+            config.ino,
+            new_config_remote_new_verified_file(service.clone(), config.remote_id)?,
+        );
     }
 
     Ok(file_pool)