Skip to content

Commit dd5b592

Browse files
committed
fix: cow_dir_cache fd-reuse bug (same class as chroot_dir_cache)
Signed-off-by: Cong Wang <cwang@multikernel.io>
1 parent 435a447 commit dd5b592

2 files changed

Lines changed: 10 additions & 4 deletions

File tree

crates/sandlock-core/src/cow/dispatch.rs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -469,8 +469,13 @@ pub(crate) async fn handle_cow_getdents(
469469
return NotifAction::Continue;
470470
}
471471

472-
// Build cache on first call
472+
// Build cache on first call; invalidate if fd was reused for a different dir.
473473
let cache_key = (pid as i32, child_fd);
474+
if let Some((cached_target, _)) = st.cow_dir_cache.get(&cache_key) {
475+
if *cached_target != target {
476+
st.cow_dir_cache.remove(&cache_key);
477+
}
478+
}
474479
if !st.cow_dir_cache.contains_key(&cache_key) {
475480
let cow = st.cow_branch.as_ref().unwrap();
476481
let workdir_str = cow.workdir_str();
@@ -511,11 +516,11 @@ pub(crate) async fn handle_cow_getdents(
511516
.unwrap_or(0);
512517
entries.push(build_dirent64(d_ino, d_off, d_type, name));
513518
}
514-
st.cow_dir_cache.insert(cache_key, entries);
519+
st.cow_dir_cache.insert(cache_key, (target.clone(), entries));
515520
}
516521

517522
let entries = match st.cow_dir_cache.get_mut(&cache_key) {
518-
Some(e) => e,
523+
Some((_, e)) => e,
519524
None => return NotifAction::Continue,
520525
};
521526

crates/sandlock-core/src/seccomp/notif.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,8 @@ pub struct SupervisorState {
8484
/// Seccomp-based COW branch (None if COW disabled).
8585
pub cow_branch: Option<crate::cow::seccomp::SeccompCowBranch>,
8686
/// Getdents cache for COW directories.
87-
pub cow_dir_cache: HashMap<(i32, u32), Vec<Vec<u8>>>,
87+
/// Value is (host_path, entries) to detect fd reuse and invalidate stale entries.
88+
pub cow_dir_cache: HashMap<(i32, u32), (String, Vec<Vec<u8>>)>,
8889
/// pidfd for the child process (for pidfd_getfd on-behalf syscalls).
8990
pub child_pidfd: Option<RawFd>,
9091
/// Event sender for dynamic policy callback (None if no policy_fn).

0 commit comments

Comments
 (0)