Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -403,6 +403,11 @@ jobs:
- name: Use specific dependency versions for Rust 1.70 compatibility.
run: |
cargo update --package=once_cell --precise=1.20.3
# tempfile 3.27 pulled edition-2024 getrandom, which Cargo 1.70 can't parse.
cargo update --package=tempfile --precise=3.23.0
# js-sys 0.3.72 has no `std` feature, and later versions require a
# wasm-bindgen newer than the Rust 1.70 resolver would otherwise pick.
cargo update --package=js-sys --precise=0.3.80
cargo update --package=uuid --precise=1.20.0

# Don't use --all-features because some of the features have dependencies
Expand All @@ -421,7 +426,7 @@ jobs:
- uses: ./.github/actions/install-rust
with:
toolchain: nightly
- run: cargo install cargo-fuzz --vers "^0.11"
- run: cargo install cargo-fuzz --version 0.13.2 --locked
- run: cargo fetch
working-directory: ./fuzz
- run: cargo fuzz build --dev
1 change: 0 additions & 1 deletion cap-primitives/src/fs/manually/open.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ use crate::fs::{
};
#[cfg(any(target_os = "android", target_os = "linux", target_os = "freebsd"))]
use rustix::fs::OFlags;
use std::borrow::Cow;
use std::ffi::OsStr;
use std::path::{Component, Path, PathBuf};
use std::{fs, io, mem};
Expand Down
16 changes: 10 additions & 6 deletions cap-primitives/src/rustix/fs/metadata_ext.rs
Original file line number Diff line number Diff line change
Expand Up @@ -145,11 +145,11 @@ impl ImplMetadataExt {
created: None,

ext: Self {
// The type of `st_dev` is `dev_t` which is signed on some
// platforms and unsigned on other platforms. A `u64` is enough
// to work for all unsigned platforms, and for signed platforms
// perform a sign extension to `i64` and then view that as an
// unsigned 64-bit number instead.
// The type of `st_dev` and `st_rdev` is `dev_t` which is
// signed on some platforms and unsigned on other platforms. A
// `u64` is enough to work for all unsigned platforms, and for
// signed platforms perform a sign extension to `i64` and then
// view that as an unsigned 64-bit number instead.
//
// Note that the `unused_comparisons` is ignored here for
// platforms where it's unsigned since the first branch here
Expand All @@ -168,7 +168,11 @@ impl ImplMetadataExt {
#[cfg(not(target_os = "wasi"))]
gid: stat.st_gid,
#[cfg(not(target_os = "wasi"))]
rdev: u64::try_from(stat.st_rdev).unwrap(),
rdev: if stat.st_rdev < 0 {
i64::try_from(stat.st_rdev).unwrap() as u64
} else {
u64::try_from(stat.st_rdev).unwrap()
},
#[cfg(not(target_os = "wasi"))]
size: u64::try_from(stat.st_size).unwrap(),
#[cfg(not(target_os = "wasi"))]
Expand Down
108 changes: 6 additions & 102 deletions tests/fs_additional.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1426,111 +1426,15 @@ fn trailing_slash_symlink() {
let sandbox = check!(tmpdir.open_dir("sandbox"));

for path in ["hidden", "hidden/", "indirect", "indirect/"] {
error!(
sandbox.open_dir(path),
"a path led outside of the filesystem"
);
error!(
sandbox.read_dir(path),
"a path led outside of the filesystem"
);
error!(
sandbox.canonicalize(path),
"a path led outside of the filesystem"
);
}
}

/// Similar to `trailing_slash_symlink`, but populates the test directory
/// outside the sandbox, so it can cover more cases.
#[test]
fn trailing_slash_symlink_more() {
let tmpdir = tempfile::tempdir().unwrap();

check!(std::fs::create_dir(tmpdir.path().join("sandbox")));
#[cfg(unix)]
{
check!(std::os::unix::fs::symlink(
"../outside",
tmpdir.path().join("sandbox/hidden")
));
check!(std::os::unix::fs::symlink(
"hidden/",
tmpdir.path().join("sandbox/indirect")
));
check!(std::os::unix::fs::symlink(
"/.",
tmpdir.path().join("sandbox/root_link")
));
}
#[cfg(windows)]
{
check!(std::os::windows::fs::symlink_dir(
"../outside",
tmpdir.path().join("sandbox/hidden")
));
check!(std::os::windows::fs::symlink_dir(
"hidden/",
tmpdir.path().join("sandbox/indirect")
));
check!(std::os::windows::fs::symlink_dir(
"/.",
tmpdir.path().join("sandbox/root_link")
));
}
#[cfg(not(any(unix, windows)))]
{
compile_error!("not implemented yet");
}

let tmpdir = check!(Dir::open_ambient_dir(tmpdir.path(), ambient_authority()));

let sandbox = check!(tmpdir.open_dir("sandbox"));

for path in [
"hidden",
"hidden/",
"indirect",
"indirect/",
"root_link",
"root_link/",
] {
error!(
sandbox.open_dir(path),
"a path led outside of the filesystem"
);
error!(
sandbox.read_dir(path),
"a path led outside of the filesystem"
);
error!(
sandbox.canonicalize(path),
"a path led outside of the filesystem"
);
}
}

/// Test interactions between symlinks and trailing slashes.
#[test]
fn trailing_slash_symlink() {
let tmpdir = tmpdir();

check!(tmpdir.create_dir("sandbox"));
check!(symlink_dir("../outside", &tmpdir, "sandbox/hidden"));
check!(symlink_dir("hidden/", &tmpdir, "sandbox/indirect"));

let sandbox = check!(tmpdir.open_dir("sandbox"));

for path in ["hidden", "hidden/", "indirect", "indirect/"] {
error!(
error_contains!(
sandbox.open_dir(path),
"a path led outside of the filesystem"
);
error!(
error_contains!(
sandbox.read_dir(path),
"a path led outside of the filesystem"
);
error!(
error_contains!(
sandbox.canonicalize(path),
"a path led outside of the filesystem"
);
Expand Down Expand Up @@ -1591,15 +1495,15 @@ fn trailing_slash_symlink_more() {
"root_link",
"root_link/",
] {
error!(
error_contains!(
sandbox.open_dir(path),
"a path led outside of the filesystem"
);
error!(
error_contains!(
sandbox.read_dir(path),
"a path led outside of the filesystem"
);
error!(
error_contains!(
sandbox.canonicalize(path),
"a path led outside of the filesystem"
);
Expand Down