diff --git a/cap-primitives/src/rustix/fs/metadata_ext.rs b/cap-primitives/src/rustix/fs/metadata_ext.rs index fd72ea0a..29813c43 100644 --- a/cap-primitives/src/rustix/fs/metadata_ext.rs +++ b/cap-primitives/src/rustix/fs/metadata_ext.rs @@ -100,6 +100,7 @@ impl MetadataExt { /// Constructs a new instance of `Metadata` from the given `Stat`. #[inline] + #[allow(unused_comparisons)] // NB: rust-lang/rust#115823 requires this here instead of on `st_dev` processing below pub(crate) fn from_rustix(stat: Stat) -> Metadata { Metadata { file_type: ImplFileTypeExt::from_raw_mode(stat.st_mode as RawMode), @@ -164,7 +165,20 @@ impl MetadataExt { created: None, ext: Self { - dev: u64::try_from(stat.st_dev).unwrap(), + // 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. + // + // Note that the `unused_comparisons` is ignored here for + // platforms where it's unsigned since the first branch here + // will never be taken. + dev: if stat.st_dev < 0 { + i64::try_from(stat.st_dev).unwrap() as u64 + } else { + u64::try_from(stat.st_dev).unwrap() + }, ino: stat.st_ino.into(), #[cfg(not(target_os = "wasi"))] mode: u32::from(stat.st_mode), diff --git a/cap-tempfile/src/tempfile.rs b/cap-tempfile/src/tempfile.rs index 2ceef0ba..88da2247 100644 --- a/cap-tempfile/src/tempfile.rs +++ b/cap-tempfile/src/tempfile.rs @@ -270,7 +270,7 @@ mod test { let metadata = tf.as_file().metadata().unwrap(); let mode = metadata.mode(); let mode = Mode::from_bits_truncate(mode); - assert_eq!(0o666 & !umask, mode.bits()); + assert_eq!(0o666 & !umask, mode.bits() & 0o777); } // And that we can write tf.write_all(b"hello world")?; diff --git a/tests/fs.rs b/tests/fs.rs index 63a6104c..483ef0c9 100644 --- a/tests/fs.rs +++ b/tests/fs.rs @@ -677,7 +677,6 @@ fn recursive_rmdir_toctou() { // deleted. let tmpdir = tmpdir(); let victim_del_path = "victim_del"; - let victim_del_path_clone = victim_del_path.clone(); // setup dest let attack_dest_dir = "attack_dest"; @@ -695,7 +694,7 @@ fn recursive_rmdir_toctou() { let tmpdir_clone = tmpdir.try_clone().unwrap(); let _t = thread::spawn(move || { while drop_canary_weak.upgrade().is_some() { - let _ = tmpdir_clone.remove_dir_all(victim_del_path_clone); + let _ = tmpdir_clone.remove_dir_all(victim_del_path); } }); diff --git a/tests/fs_utf8.rs b/tests/fs_utf8.rs index 43788539..8d88e7c0 100644 --- a/tests/fs_utf8.rs +++ b/tests/fs_utf8.rs @@ -680,7 +680,6 @@ fn recursive_rmdir_toctou() { // deleted. let tmpdir = tmpdir(); let victim_del_path = "victim_del"; - let victim_del_path_clone = victim_del_path.clone(); // setup dest let attack_dest_dir = "attack_dest"; @@ -698,7 +697,7 @@ fn recursive_rmdir_toctou() { let tmpdir_clone = tmpdir.try_clone().unwrap(); let _t = thread::spawn(move || { while drop_canary_weak.upgrade().is_some() { - let _ = tmpdir_clone.remove_dir_all(victim_del_path_clone); + let _ = tmpdir_clone.remove_dir_all(victim_del_path); } });