Skip to content

Commit 9bfa01a

Browse files
committed
sandlock-core: drop redundant symlink-target deny
Signed-off-by: Cong Wang <cwang@multikernel.io>
1 parent a3f929d commit 9bfa01a

2 files changed

Lines changed: 13 additions & 16 deletions

File tree

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

Lines changed: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1313,13 +1313,10 @@ fn resolve_path_for_notif(notif: &SeccompNotif, notif_fd: RawFd) -> Option<Strin
13131313
let path = read_path_for_event(notif, notif.data.args[1], notif_fd)?;
13141314
resolve_at_path_for_event(notif, notif.data.args[0] as i64, &path)
13151315
}
1316-
// symlinkat(target, newdirfd, linkpath)
1317-
// The target string is what the symlink points to; deny if it names a denied path.
1318-
n if n == libc::SYS_symlinkat => {
1319-
let target = read_path_for_event(notif, notif.data.args[0], notif_fd)?;
1320-
// target may be absolute or relative to the process cwd
1321-
resolve_at_path_for_event(notif, libc::AT_FDCWD as i64, &target)
1322-
}
1316+
// symlinkat/symlink intentionally omitted: creating a symlink does
1317+
// not access its target, so there is nothing to gate here. Any later
1318+
// open through the symlink resolves to the real target and is denied
1319+
// race-free on the open path (issue #111). See `on_behalf_open_for_deny`.
13231320
// link(oldpath, newpath) — legacy, AT_FDCWD implied for both
13241321
n if Some(n) == arch::sys_link() => {
13251322
let path = read_path_for_event(notif, notif.data.args[0], notif_fd)?;
@@ -1330,11 +1327,6 @@ fn resolve_path_for_notif(notif: &SeccompNotif, notif_fd: RawFd) -> Option<Strin
13301327
let path = read_path_for_event(notif, notif.data.args[0], notif_fd)?;
13311328
resolve_at_path_for_event(notif, libc::AT_FDCWD as i64, &path)
13321329
}
1333-
// symlink(target, linkpath) — legacy
1334-
n if Some(n) == arch::sys_symlink() => {
1335-
let target = read_path_for_event(notif, notif.data.args[0], notif_fd)?;
1336-
resolve_at_path_for_event(notif, libc::AT_FDCWD as i64, &target)
1337-
}
13381330
_ => None,
13391331
}
13401332
}
@@ -1620,12 +1612,15 @@ async fn handle_notification(
16201612
// Check dynamic path denials before dispatch
16211613
let mut action = {
16221614
let nr = notif.data.nr as i64;
1615+
// symlinkat/symlink are not gated: creating a symlink does not access
1616+
// its target (any open through it is denied race-free on the open
1617+
// path). See `resolve_path_for_notif`.
16231618
let mut path_check_nrs = vec![
16241619
libc::SYS_openat, arch::SYS_OPENAT2, libc::SYS_execve, libc::SYS_execveat,
1625-
libc::SYS_linkat, libc::SYS_renameat2, libc::SYS_symlinkat,
1620+
libc::SYS_linkat, libc::SYS_renameat2,
16261621
];
16271622
path_check_nrs.extend([
1628-
arch::sys_open(), arch::sys_link(), arch::sys_rename(), arch::sys_symlink(),
1623+
arch::sys_open(), arch::sys_link(), arch::sys_rename(),
16291624
].into_iter().flatten());
16301625
let should_precheck_denied = policy.chroot_root.is_none()
16311626
&& path_check_nrs.contains(&nr);

crates/sandlock-core/src/seccomp_plan.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -232,21 +232,23 @@ fn chroot_path_syscalls() -> Vec<i64> {
232232
}
233233

234234
fn fs_denied_path_syscalls() -> Vec<i64> {
235+
// symlinkat/symlink are intentionally absent: creating a symlink does not
236+
// access its target, so there is nothing to deny at creation time. A later
237+
// open through the symlink resolves to the real target and is denied
238+
// race-free on the open path (issue #111).
235239
let mut v = vec![
236240
libc::SYS_openat,
237241
arch::SYS_OPENAT2,
238242
libc::SYS_execve,
239243
libc::SYS_execveat,
240244
libc::SYS_linkat,
241245
libc::SYS_renameat2,
242-
libc::SYS_symlinkat,
243246
];
244247
v.extend(
245248
[
246249
arch::sys_open(),
247250
arch::sys_link(),
248251
arch::sys_rename(),
249-
arch::sys_symlink(),
250252
]
251253
.into_iter()
252254
.flatten(),

0 commit comments

Comments
 (0)