-
Notifications
You must be signed in to change notification settings - Fork 31
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Use AT_/O_RESOLVE_BENEATH on FreeBSD >= 13.0, fixes #180
- Loading branch information
1 parent
91372b8
commit e312746
Showing
16 changed files
with
242 additions
and
16 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
use rustix::fs::{statat, AtFlags}; | ||
use std::fs; | ||
use std::sync::atomic::{AtomicBool, Ordering::Relaxed}; | ||
|
||
static WORKING: AtomicBool = AtomicBool::new(false); | ||
static CHECKED: AtomicBool = AtomicBool::new(false); | ||
|
||
#[inline] | ||
pub(crate) fn beneath_supported(start: &fs::File) -> bool { | ||
if WORKING.load(Relaxed) { | ||
return true; | ||
} | ||
if CHECKED.load(Relaxed) { | ||
return false; | ||
} | ||
// Unknown O_ flags get ignored but AT_ flags have strict checks, so we use that. | ||
if let Err(rustix::io::Errno::INVAL) = | ||
statat(start, "", AtFlags::EMPTY_PATH | AtFlags::RESOLVE_BENEATH) | ||
{ | ||
CHECKED.store(true, Relaxed); | ||
false | ||
} else { | ||
WORKING.store(true, Relaxed); | ||
true | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
mod check; | ||
mod open_entry_impl; | ||
mod open_impl; | ||
mod remove_dir_impl; | ||
mod remove_file_impl; | ||
mod set_permissions_impl; | ||
mod set_times_impl; | ||
mod stat_impl; | ||
|
||
pub(crate) use crate::fs::manually::canonicalize as canonicalize_impl; | ||
pub(crate) use check::beneath_supported; | ||
pub(crate) use open_entry_impl::open_entry_impl; | ||
pub(crate) use open_impl::open_impl; | ||
pub(crate) use remove_dir_impl::remove_dir_impl; | ||
pub(crate) use remove_file_impl::remove_file_impl; | ||
pub(crate) use set_permissions_impl::set_permissions_impl; | ||
pub(crate) use set_times_impl::{set_times_impl, set_times_nofollow_impl}; | ||
pub(crate) use stat_impl::stat_impl; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
use crate::fs::{open_impl, OpenOptions}; | ||
use std::ffi::OsStr; | ||
use std::{fs, io}; | ||
|
||
#[inline(always)] | ||
pub(crate) fn open_entry_impl( | ||
start: &fs::File, | ||
path: &OsStr, | ||
options: &OpenOptions, | ||
) -> io::Result<fs::File> { | ||
open_impl(start, path.as_ref(), options) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
use super::super::super::fs::compute_oflags; | ||
use crate::fs::{errors, manually, OpenOptions}; | ||
use io_lifetimes::FromFd; | ||
use rustix::fs::{openat, Mode, OFlags, RawMode}; | ||
use std::path::Path; | ||
use std::{fs, io}; | ||
|
||
pub(crate) fn open_impl( | ||
start: &fs::File, | ||
path: &Path, | ||
options: &OpenOptions, | ||
) -> io::Result<fs::File> { | ||
if !super::beneath_supported(start) { | ||
return manually::open(start, path, options); | ||
} | ||
|
||
let oflags = compute_oflags(options)? | OFlags::RESOLVE_BENEATH; | ||
|
||
let mode = if oflags.contains(OFlags::CREATE) { | ||
Mode::from_bits((options.ext.mode & 0o7777) as RawMode).unwrap() | ||
} else { | ||
Mode::empty() | ||
}; | ||
|
||
match openat(start, path, oflags, mode) { | ||
Ok(file) => Ok(fs::File::from_into_fd(file)), | ||
Err(rustix::io::Errno::NOTCAPABLE) => Err(errors::escape_attempt()), | ||
Err(err) => Err(err.into()), | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
use crate::fs::via_parent; | ||
use rustix::fs::{unlinkat, AtFlags}; | ||
use std::path::Path; | ||
use std::{fs, io}; | ||
|
||
pub(crate) fn remove_dir_impl(start: &fs::File, path: &Path) -> io::Result<()> { | ||
if !super::beneath_supported(start) { | ||
return via_parent::remove_dir(start, path); | ||
} | ||
|
||
Ok(unlinkat( | ||
start, | ||
path, | ||
AtFlags::RESOLVE_BENEATH | AtFlags::REMOVEDIR, | ||
)?) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
use crate::fs::via_parent; | ||
use rustix::fs::{unlinkat, AtFlags}; | ||
use std::path::Path; | ||
use std::{fs, io}; | ||
|
||
pub(crate) fn remove_file_impl(start: &fs::File, path: &Path) -> io::Result<()> { | ||
if !super::beneath_supported(start) { | ||
return via_parent::remove_file(start, path); | ||
} | ||
|
||
Ok(unlinkat(start, path, AtFlags::RESOLVE_BENEATH)?) | ||
} |
22 changes: 22 additions & 0 deletions
22
cap-primitives/src/rustix/freebsd/fs/set_permissions_impl.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
use crate::fs::Permissions; | ||
use rustix::fs::{chmodat, AtFlags, Mode}; | ||
use std::os::unix::fs::PermissionsExt; | ||
use std::path::Path; | ||
use std::{fs, io}; | ||
|
||
pub(crate) fn set_permissions_impl( | ||
start: &fs::File, | ||
path: &Path, | ||
perm: Permissions, | ||
) -> io::Result<()> { | ||
if !super::beneath_supported(start) { | ||
return super::super::super::fs::set_permissions_manually(start, path, perm); | ||
} | ||
|
||
Ok(chmodat( | ||
start, | ||
path, | ||
Mode::from_raw_mode(perm.mode() as _), | ||
AtFlags::RESOLVE_BENEATH, | ||
)?) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
use crate::fs::{to_timespec, via_parent, SystemTimeSpec}; | ||
use rustix::fs::{utimensat, AtFlags, Timestamps}; | ||
use std::path::Path; | ||
use std::{fs, io}; | ||
|
||
pub(crate) fn set_times_impl( | ||
start: &fs::File, | ||
path: &Path, | ||
atime: Option<SystemTimeSpec>, | ||
mtime: Option<SystemTimeSpec>, | ||
) -> io::Result<()> { | ||
if !super::beneath_supported(start) { | ||
return super::super::super::fs::set_times_manually(start, path, atime, mtime); | ||
} | ||
|
||
let times = Timestamps { | ||
last_access: to_timespec(atime)?, | ||
last_modification: to_timespec(mtime)?, | ||
}; | ||
|
||
Ok(utimensat(start, path, ×, AtFlags::RESOLVE_BENEATH)?) | ||
} | ||
|
||
pub(crate) fn set_times_nofollow_impl( | ||
start: &fs::File, | ||
path: &Path, | ||
atime: Option<SystemTimeSpec>, | ||
mtime: Option<SystemTimeSpec>, | ||
) -> io::Result<()> { | ||
if !super::beneath_supported(start) { | ||
return via_parent::set_times_nofollow(start, path, atime, mtime); | ||
} | ||
|
||
let times = Timestamps { | ||
last_access: to_timespec(atime)?, | ||
last_modification: to_timespec(mtime)?, | ||
}; | ||
|
||
Ok(utimensat( | ||
start, | ||
path, | ||
×, | ||
AtFlags::RESOLVE_BENEATH | AtFlags::SYMLINK_NOFOLLOW, | ||
)?) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
use crate::fs::{manually, FollowSymlinks, Metadata, MetadataExt}; | ||
use rustix::fs::{statat, AtFlags}; | ||
use std::path::Path; | ||
use std::{fs, io}; | ||
|
||
pub(crate) fn stat_impl( | ||
start: &fs::File, | ||
path: &Path, | ||
follow: FollowSymlinks, | ||
) -> io::Result<Metadata> { | ||
if !super::beneath_supported(start) { | ||
return manually::stat(start, path, follow); | ||
} | ||
|
||
let flags = AtFlags::RESOLVE_BENEATH | ||
| if follow == FollowSymlinks::Yes { | ||
AtFlags::empty() | ||
} else { | ||
AtFlags::SYMLINK_NOFOLLOW | ||
}; | ||
Ok(MetadataExt::from_rustix(statat(start, path, flags)?)) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
pub(crate) mod fs; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters