diff --git a/cap-primitives/src/rustix/linux/fs/open_impl.rs b/cap-primitives/src/rustix/linux/fs/open_impl.rs index edb4c8bd..95161b76 100644 --- a/cap-primitives/src/rustix/linux/fs/open_impl.rs +++ b/cap-primitives/src/rustix/linux/fs/open_impl.rs @@ -9,6 +9,7 @@ #[cfg(racy_asserts)] use crate::fs::is_same_file; +use crate::fs::FollowSymlinks; use crate::fs::{manually, OpenOptions}; use std::path::Path; use std::{fs, io}; @@ -82,13 +83,11 @@ pub(crate) fn open_beneath( // times, because there's no limit on how often this can happen. The actual // number here is currently an arbitrarily chosen guess. for _ in 0..4 { - match openat2( - start, - path_c_str, - oflags, - mode, - ResolveFlags::BENEATH | ResolveFlags::NO_MAGICLINKS, - ) { + let mut resolve_flags = ResolveFlags::BENEATH | ResolveFlags::NO_MAGICLINKS; + if options.follow == FollowSymlinks::No { + resolve_flags |= ResolveFlags::NO_SYMLINKS; + } + match openat2(start, path_c_str, oflags, mode, resolve_flags) { Ok(file) => { let file = fs::File::from_into_fd(file); diff --git a/tests/symlinks.rs b/tests/symlinks.rs index 5323a881..6628d6eb 100644 --- a/tests/symlinks.rs +++ b/tests/symlinks.rs @@ -258,19 +258,19 @@ fn open_dir_nofollow() { let name = format!("{}{}", symlink_dir, suffix); check!(tmpdir.open_dir(&name)); // On Windows, a trailing dot is stripped early. - if cfg!(not(windows)) || suffix != &"/." { - check!(tmpdir.open_dir_nofollow(&name)); - } else { + if cfg!(windows) || suffix == &"/." || cfg!(target_os = "linux") { assert!(tmpdir.open_dir_nofollow(&name).is_err()); + } else { + check!(tmpdir.open_dir_nofollow(&name)); } for dir_name in &["dir", "symlink_dir"] { let name = format!("{}/../{}", dir_name, name); check!(tmpdir.open_dir(&name)); // On Windows, a trailing dot is stripped early. - if cfg!(not(windows)) || suffix != &"/." { - check!(tmpdir.open_dir_nofollow(&name)); - } else { + if cfg!(windows) || suffix == &"/." || cfg!(target_os = "linux") { assert!(tmpdir.open_dir_nofollow(&name).is_err()); + } else { + check!(tmpdir.open_dir_nofollow(&name)); } } } @@ -296,7 +296,11 @@ fn open_dir_nofollow() { #[cfg(not(windows))] { check!(tmpdir.open_dir(&name)); - check!(tmpdir.open_dir_nofollow(&name)); + if cfg!(target_os = "linux") { + assert!(tmpdir.open_dir_nofollow(&name).is_err()); + } else { + check!(tmpdir.open_dir_nofollow(&name)); + } } for dir_name in &["dir", "symlink_dir"] { let name = format!("{}/../{}", dir_name, name); @@ -308,7 +312,11 @@ fn open_dir_nofollow() { #[cfg(not(windows))] { check!(tmpdir.open_dir(&name)); - check!(tmpdir.open_dir_nofollow(&name)); + if cfg!(target_os = "linux") { + assert!(tmpdir.open_dir_nofollow(&name).is_err()); + } else { + check!(tmpdir.open_dir_nofollow(&name)); + } } } }