瀏覽代碼

Took steps to obscure the superblock path.

Matthew Carr 2 年之前
父節點
當前提交
d8284bb88e
共有 1 個文件被更改,包括 64 次插入30 次删除
  1. 64 30
      crates/btfproto/src/local_fs.rs

+ 64 - 30
crates/btfproto/src/local_fs.rs

@@ -610,7 +610,7 @@ mod private {
     impl<C, A> LocalFs<C, A> {
         /// The maximum number of directory entries that can be returned in any given call to
         /// `read_dir`.
-        const DIR_ENTRY_LIMIT: usize = 1024;
+        const READ_DIR_LIMIT: usize = 1024;
     }
 
     impl<C: Creds + 'static, A: Authorizer> LocalFs<C, A> {
@@ -626,8 +626,13 @@ mod private {
             let root_principal = writecap.root_principal();
 
             // Initialize the superblock.
-            let mut sb_block =
-                Self::open_superblock(&btdir, creds.clone(), root_block_path.clone())?;
+            let mut sb_block = Self::open_superblock(
+                &btdir,
+                creds.clone(),
+                root_block_path.clone(),
+                &root_principal,
+                true,
+            )?;
             let sb = Superblock {
                 generation,
                 next_inode: AtomicU64::new(SpecInodes::FirstFree.into()),
@@ -705,8 +710,13 @@ mod private {
             let writecap = creds.writecap().ok_or(BlockError::MissingWritecap)?;
             let root_block_path = writecap.root_block_path();
             let root_principal = writecap.root_principal();
-            let mut sb_block =
-                Self::open_superblock(&btdir, creds.clone(), root_block_path.clone())?;
+            let mut sb_block = Self::open_superblock(
+                &btdir,
+                creds.clone(),
+                root_block_path.clone(),
+                &root_principal,
+                false,
+            )?;
             let sb: Superblock = read_from(&mut sb_block)?;
             let root_block = Self::open_block(
                 &btdir,
@@ -760,16 +770,60 @@ mod private {
             })
         }
 
+        fn make_path<P: AsRef<Path>>(parent: P, file_name: &str) -> PathBuf {
+            let mut path =
+                PathBuf::with_capacity(parent.as_ref().as_os_str().len() + 1 + file_name.len() + 1);
+            path.push(parent);
+            path.push(&file_name[..2]);
+            path.push(&file_name[2..]);
+            path
+        }
+
+        fn hex_encode(src: &[u8]) -> Result<String> {
+            use std::fmt::Write;
+            let mut string = String::with_capacity(2 * src.len());
+            for byte in src.iter() {
+                write!(string, "{byte:02x}")?;
+            }
+            Ok(string)
+        }
+
+        fn ensure_parent_created(path: &Path) -> Result<()> {
+            let dir = path.ancestors().nth(1).unwrap();
+            if let Err(err) = std::fs::create_dir(dir) {
+                match err.kind() {
+                    io::ErrorKind::AlreadyExists => Ok(()),
+                    _ => Err(err.into()),
+                }
+            } else {
+                Ok(())
+            }
+        }
+
         fn open_superblock<P: AsRef<Path>>(
             btdir: P,
             creds: C,
             block_path: BlockPath,
+            root_principal: &Principal,
+            create_new: bool,
         ) -> Result<Accessor<FileBlock<C>>> {
-            let path = btdir.as_ref().join("super.blk");
+            const HASH: HashKind = HashKind::Sha2_256;
+            let mut buf = [0u8; HASH.len()];
+            HASH.digest(
+                &mut buf,
+                [
+                    SpecInodes::Sb.value().to_le_bytes().as_slice(),
+                    root_principal.as_slice(),
+                ]
+                .into_iter(),
+            )?;
+            let hex_str = Self::hex_encode(&buf)?;
+            let path = Self::make_path(btdir, &hex_str);
+            Self::ensure_parent_created(&path)?;
             let file = std::fs::OpenOptions::new()
                 .read(true)
                 .write(true)
-                .create(true)
+                .create_new(create_new)
                 .open(path)?;
             let block = BlockOpenOptions::new()
                 .with_creds(creds)
@@ -780,15 +834,6 @@ mod private {
             Ok(block)
         }
 
-        fn hex_encode(src: &[u8]) -> Result<String> {
-            use std::fmt::Write;
-            let mut string = String::with_capacity(2 * src.len());
-            for byte in src.iter() {
-                write!(string, "{byte:02x}")?;
-            }
-            Ok(string)
-        }
-
         /// Returns the path to the file storing the given inode's data.
         fn block_path<P: AsRef<Path>>(
             parent: P,
@@ -802,12 +847,7 @@ mod private {
                 [inode.to_le_bytes().as_slice(), inode_key].into_iter(),
             )?;
             let hex_str = Self::hex_encode(&buf)?;
-            let mut path =
-                PathBuf::with_capacity(parent.as_ref().as_os_str().len() + 1 + hex_str.len() + 1);
-            path.push(parent);
-            path.push(&hex_str[..2]);
-            path.push(&hex_str[2..]);
-            Ok(path)
+            Ok(Self::make_path(parent, &hex_str))
         }
 
         fn open_block<P: AsRef<Path>>(
@@ -820,13 +860,7 @@ mod private {
             inode_key: &[u8],
         ) -> Result<Accessor<FileBlock<C>>> {
             let path = Self::block_path(&btdir, inode, inode_hash, inode_key)?;
-            let dir = path.ancestors().nth(1).unwrap();
-            if let Err(err) = std::fs::create_dir(dir) {
-                match err.kind() {
-                    io::ErrorKind::AlreadyExists => (),
-                    _ => return Err(err.into()),
-                }
-            }
+            Self::ensure_parent_created(&path)?;
             let file = std::fs::OpenOptions::new()
                 .read(true)
                 .write(true)
@@ -1507,7 +1541,7 @@ mod private {
                 owner.assert_eq(from)?;
                 let dir = handle_value.directory()?;
                 let state: usize = state.try_into()?;
-                let server_limit = Self::DIR_ENTRY_LIMIT.min(dir.num_entries() - state);
+                let server_limit = Self::READ_DIR_LIMIT.min(dir.num_entries() - state);
                 let entries_len = if limit > 0 {
                     server_limit.min(limit as usize)
                 } else {