Skip to content

Commit 4e8ba00

Browse files
authored
Fix Dir::symlink_metadata of "/" on Linux. (#396)
Fix an overzealous optimization on Linux which inappropriately allowed `Dir::symlink_metadata` on a path of "/" to succeed. Fixes bytecodealliance/wasmtime#11606.
1 parent c9e1145 commit 4e8ba00

File tree

2 files changed

+26
-5
lines changed

2 files changed

+26
-5
lines changed

cap-primitives/src/rustix/linux/fs/stat_impl.rs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,14 @@ pub(crate) fn stat_impl(
1818
use crate::fs::{stat_unchecked, OpenOptionsExt};
1919
use std::path::Component;
2020

21-
// Optimization: if path has exactly one component and it's not ".." and
22-
// we're not following symlinks we can go straight to `stat_unchecked`,
23-
// which is faster than doing an open with a separate fstat.
21+
// Optimization: if path has exactly one component and it's not ".." or
22+
// anything non-normal and we're not following symlinks we can go straight
23+
// to `stat_unchecked`, which is faster than doing an open with a separate
24+
// `fstat`.
2425
if follow == FollowSymlinks::No {
2526
let mut components = path.components();
26-
if let Some(component) = components.next() {
27-
if components.next().is_none() && component != Component::ParentDir {
27+
if let Some(Component::Normal(component)) = components.next() {
28+
if components.next().is_none() {
2829
return stat_unchecked(start, component.as_ref(), FollowSymlinks::No);
2930
}
3031
}

tests/fs_additional.rs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1380,3 +1380,23 @@ fn dotdot_slashdot_at_end_of_symlink_all_inside_dir() {
13801380
let _entry = check!(entry);
13811381
}
13821382
}
1383+
1384+
/// Ensure that a path of "/" is rejected.
1385+
#[test]
1386+
fn statat_slash() {
1387+
let tmpdir = tmpdir();
1388+
1389+
error_contains!(tmpdir.metadata("/"), "a path led outside of the filesystem");
1390+
error_contains!(
1391+
tmpdir.metadata("/foo"),
1392+
"a path led outside of the filesystem"
1393+
);
1394+
error_contains!(
1395+
tmpdir.symlink_metadata("/"),
1396+
"a path led outside of the filesyste"
1397+
);
1398+
error_contains!(
1399+
tmpdir.symlink_metadata("/foo"),
1400+
"a path led outside of the filesyste"
1401+
);
1402+
}

0 commit comments

Comments
 (0)