Skip to content

Commit 5e9248c

Browse files
authored
Fix stats where st_dev is negative (#329)
* Fix stats where `st_dev` is negative This is intended to be a fix for bytecodealliance/wasmtime#6978 where some platforms use a signed integer for the `dev_t` type and it looks like some `st_dev` fields can indeed be negative. * Move lint location * Comment odd location of `#[allow]` * Fix a warning on beta Rust * Fix a failing tempfile test Bisection points at bytecodealliance/rustix#787 as other flags are coming into the `Mode` enum which means that the `mode.bits()` is `0o100644` which wasn't being tested for. The unknown bits are masked off now.
1 parent 963eebf commit 5e9248c

File tree

4 files changed

+18
-6
lines changed

4 files changed

+18
-6
lines changed

cap-primitives/src/rustix/fs/metadata_ext.rs

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ impl MetadataExt {
100100

101101
/// Constructs a new instance of `Metadata` from the given `Stat`.
102102
#[inline]
103+
#[allow(unused_comparisons)] // NB: rust-lang/rust#115823 requires this here instead of on `st_dev` processing below
103104
pub(crate) fn from_rustix(stat: Stat) -> Metadata {
104105
Metadata {
105106
file_type: ImplFileTypeExt::from_raw_mode(stat.st_mode as RawMode),
@@ -164,7 +165,20 @@ impl MetadataExt {
164165
created: None,
165166

166167
ext: Self {
167-
dev: u64::try_from(stat.st_dev).unwrap(),
168+
// The type of `st_dev` is `dev_t` which is signed on some
169+
// platforms and unsigned on other platforms. A `u64` is enough
170+
// to work for all unsigned platforms, and for signed platforms
171+
// perform a sign extension to `i64` and then view that as an
172+
// unsigned 64-bit number instead.
173+
//
174+
// Note that the `unused_comparisons` is ignored here for
175+
// platforms where it's unsigned since the first branch here
176+
// will never be taken.
177+
dev: if stat.st_dev < 0 {
178+
i64::try_from(stat.st_dev).unwrap() as u64
179+
} else {
180+
u64::try_from(stat.st_dev).unwrap()
181+
},
168182
ino: stat.st_ino.into(),
169183
#[cfg(not(target_os = "wasi"))]
170184
mode: u32::from(stat.st_mode),

cap-tempfile/src/tempfile.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -270,7 +270,7 @@ mod test {
270270
let metadata = tf.as_file().metadata().unwrap();
271271
let mode = metadata.mode();
272272
let mode = Mode::from_bits_truncate(mode);
273-
assert_eq!(0o666 & !umask, mode.bits());
273+
assert_eq!(0o666 & !umask, mode.bits() & 0o777);
274274
}
275275
// And that we can write
276276
tf.write_all(b"hello world")?;

tests/fs.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -677,7 +677,6 @@ fn recursive_rmdir_toctou() {
677677
// deleted.
678678
let tmpdir = tmpdir();
679679
let victim_del_path = "victim_del";
680-
let victim_del_path_clone = victim_del_path.clone();
681680

682681
// setup dest
683682
let attack_dest_dir = "attack_dest";
@@ -695,7 +694,7 @@ fn recursive_rmdir_toctou() {
695694
let tmpdir_clone = tmpdir.try_clone().unwrap();
696695
let _t = thread::spawn(move || {
697696
while drop_canary_weak.upgrade().is_some() {
698-
let _ = tmpdir_clone.remove_dir_all(victim_del_path_clone);
697+
let _ = tmpdir_clone.remove_dir_all(victim_del_path);
699698
}
700699
});
701700

tests/fs_utf8.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -680,7 +680,6 @@ fn recursive_rmdir_toctou() {
680680
// deleted.
681681
let tmpdir = tmpdir();
682682
let victim_del_path = "victim_del";
683-
let victim_del_path_clone = victim_del_path.clone();
684683

685684
// setup dest
686685
let attack_dest_dir = "attack_dest";
@@ -698,7 +697,7 @@ fn recursive_rmdir_toctou() {
698697
let tmpdir_clone = tmpdir.try_clone().unwrap();
699698
let _t = thread::spawn(move || {
700699
while drop_canary_weak.upgrade().is_some() {
701-
let _ = tmpdir_clone.remove_dir_all(victim_del_path_clone);
700+
let _ = tmpdir_clone.remove_dir_all(victim_del_path);
702701
}
703702
});
704703

0 commit comments

Comments
 (0)