@@ -1487,6 +1487,7 @@ mod remove_dir_impl {
1487
1487
use crate :: sync:: Arc ;
1488
1488
use crate :: sys:: { cvt, cvt_r} ;
1489
1489
use alloc:: collections:: VecDeque ;
1490
+ use libc:: dev_t;
1490
1491
1491
1492
#[ cfg( not( all( target_os = "macos" , target_arch = "x86_64" ) , ) ) ]
1492
1493
use libc:: { fdopendir, openat, unlinkat} ;
@@ -1640,27 +1641,33 @@ mod remove_dir_impl {
1640
1641
1641
1642
struct DirComponent {
1642
1643
name : CString ,
1644
+ dev : dev_t ,
1643
1645
ino : u64 ,
1644
1646
}
1645
1647
1646
1648
fn readdir_open_path ( path : & CStr ) -> io:: Result < ( DirComponent , CachedReadDir ) > {
1647
1649
let dir_fd = openat_nofollow_dironly ( None , path) ?;
1648
1650
1649
- // use fstat() to get the inode of the directory
1651
+ // use fstat() to get dev, inode of the directory
1650
1652
let mut stat = unsafe { mem:: zeroed ( ) } ;
1651
1653
cvt ( unsafe { fstat64 ( dir_fd. as_raw_fd ( ) , & mut stat) } ) ?;
1652
1654
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
+ ) )
1654
1659
}
1655
1660
1656
1661
fn readdir_open_child (
1657
1662
readdir : & CachedReadDir ,
1658
1663
child : & DirEntry ,
1659
1664
) -> io:: Result < ( DirComponent , CachedReadDir ) > {
1660
1665
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) } ) ?;
1661
1668
let cached_readdir = fdreaddir ( dir_fd) ?;
1662
1669
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 } ,
1664
1671
cached_readdir,
1665
1672
) )
1666
1673
}
@@ -1676,7 +1683,7 @@ mod remove_dir_impl {
1676
1683
cvt ( unsafe { fstat64 ( parent_dir_fd. as_raw_fd ( ) , & mut stat) } ) ?;
1677
1684
// Make sure that the reopened parent directory has the same inode as when we visited it descending
1678
1685
// 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 {
1680
1687
return Err ( io:: Error :: new (
1681
1688
io:: ErrorKind :: Uncategorized ,
1682
1689
"parent directory inode does not match" ,
0 commit comments