Skip to content

Commit 65b740c

Browse files
committed
Store and compare with stat.st_dev as well when going back up via ..
1 parent 424189d commit 65b740c

File tree

1 file changed

+11
-4
lines changed
  • library/std/src/sys/unix

1 file changed

+11
-4
lines changed

Diff for: library/std/src/sys/unix/fs.rs

+11-4
Original file line numberDiff line numberDiff line change
@@ -1487,6 +1487,7 @@ mod remove_dir_impl {
14871487
use crate::sync::Arc;
14881488
use crate::sys::{cvt, cvt_r};
14891489
use alloc::collections::VecDeque;
1490+
use libc::dev_t;
14901491

14911492
#[cfg(not(all(target_os = "macos", target_arch = "x86_64"),))]
14921493
use libc::{fdopendir, openat, unlinkat};
@@ -1640,27 +1641,33 @@ mod remove_dir_impl {
16401641

16411642
struct DirComponent {
16421643
name: CString,
1644+
dev: dev_t,
16431645
ino: u64,
16441646
}
16451647

16461648
fn readdir_open_path(path: &CStr) -> io::Result<(DirComponent, CachedReadDir)> {
16471649
let dir_fd = openat_nofollow_dironly(None, path)?;
16481650

1649-
// use fstat() to get the inode of the directory
1651+
// use fstat() to get dev, inode of the directory
16501652
let mut stat = unsafe { mem::zeroed() };
16511653
cvt(unsafe { fstat64(dir_fd.as_raw_fd(), &mut stat) })?;
16521654
let cached_readdir = fdreaddir(dir_fd)?;
1653-
Ok((DirComponent { name: CString::new("")?, ino: stat.st_ino }, cached_readdir))
1655+
Ok((
1656+
DirComponent { name: CString::new("")?, dev: stat.st_dev, ino: stat.st_ino },
1657+
cached_readdir,
1658+
))
16541659
}
16551660

16561661
fn readdir_open_child(
16571662
readdir: &CachedReadDir,
16581663
child: &DirEntry,
16591664
) -> io::Result<(DirComponent, CachedReadDir)> {
16601665
let dir_fd = openat_nofollow_dironly(Some(readdir.as_fd()), child.name_cstr())?;
1666+
let mut stat = unsafe { mem::zeroed() };
1667+
cvt(unsafe { fstat64(dir_fd.as_raw_fd(), &mut stat) })?;
16611668
let cached_readdir = fdreaddir(dir_fd)?;
16621669
Ok((
1663-
DirComponent { name: child.name_cstr().into(), ino: child.entry.d_ino },
1670+
DirComponent { name: child.name_cstr().into(), dev: stat.st_dev, ino: stat.st_ino },
16641671
cached_readdir,
16651672
))
16661673
}
@@ -1676,7 +1683,7 @@ mod remove_dir_impl {
16761683
cvt(unsafe { fstat64(parent_dir_fd.as_raw_fd(), &mut stat) })?;
16771684
// Make sure that the reopened parent directory has the same inode as when we visited it descending
16781685
// the directory tree. More detailed risk analysis TBD.
1679-
if expected_parent_dir.ino != stat.st_ino {
1686+
if expected_parent_dir.dev != stat.st_dev || expected_parent_dir.ino != stat.st_ino {
16801687
return Err(io::Error::new(
16811688
io::ErrorKind::Uncategorized,
16821689
"parent directory inode does not match",

0 commit comments

Comments
 (0)