@@ -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) ;
0 commit comments