From 07de998507471ea2b6c50792b57ed04299237904 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sosth=C3=A8ne=20Gu=C3=A9don?= Date: Mon, 1 Jun 2026 17:35:20 +0200 Subject: [PATCH] Fix absolute paths being accepted when they shouldn't --- src/store/filestore.rs | 32 +++++++++++++++++++++++++++++++- tests/filesystem.rs | 11 +++++++++++ 2 files changed, 42 insertions(+), 1 deletion(-) diff --git a/src/store/filestore.rs b/src/store/filestore.rs index cbedf19e909..f9a5635710e 100644 --- a/src/store/filestore.rs +++ b/src/store/filestore.rs @@ -53,7 +53,7 @@ impl ClientFilestore { /// Client files are store below `//dat/`. pub fn actual_path(&self, client_path: &Path) -> Result { // Clients must not escape their namespace - if client_path.as_ref().contains("..") { + if client_path.as_str().contains("..") || client_path.as_str().starts_with("/") { return Err(Error::InvalidPath); } @@ -514,3 +514,33 @@ impl Filestore for ClientFilestore { Ok(path) } } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn actual_path_root() { + let client_path = path!("/testclient"); + struct DummyStore; + impl Store for DummyStore { + fn ifs(&self) -> &dyn DynFilesystem { + panic!() + } + fn efs(&self) -> &dyn DynFilesystem { + panic!() + } + fn vfs(&self) -> &dyn DynFilesystem { + panic!() + } + } + + let filestore = ClientFilestore { + base: PathBuf::from_path(client_path), + store: DummyStore, + }; + + assert!(filestore.actual_path(path!("/")).is_err()); + assert!(filestore.actual_path(path!("/test")).is_err()); + } +} diff --git a/tests/filesystem.rs b/tests/filesystem.rs index 5766b47fcc3..f8c1ee068b5 100644 --- a/tests/filesystem.rs +++ b/tests/filesystem.rs @@ -55,6 +55,17 @@ fn escape_namespace_root() { }) } +#[test] +fn escape_namespace_root_only() { + client::get(|client| { + let key = syscall!(client.generate_key(Mechanism::P256, StorageAttributes::new())).key; + let mut path = PathBuf::from(path!("/")); + path.push(path!("sec")); + path.push(&key.legacy_hex_path()); + assert!(try_syscall!(client.read_file(Location::Volatile, path)).is_err()); + }) +} + fn iterating(location: Location) { client::get(|client| { syscall!(client.write_file(