Skip to content

Commit 0d3b069

Browse files
committed
fuser gap audit fixes
1 parent b5374d4 commit 0d3b069

File tree

1 file changed

+38
-11
lines changed

1 file changed

+38
-11
lines changed

process/fuser.rs

Lines changed: 38 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -324,7 +324,11 @@ mod linux {
324324
}
325325
}
326326

327-
pub fn get_matched_procs(file: Vec<PathBuf>, mount: bool) -> Result<Vec<Names>, io::Error> {
327+
pub fn get_matched_procs(
328+
file: Vec<PathBuf>,
329+
mount: bool,
330+
named_files: bool,
331+
) -> Result<Vec<Names>, io::Error> {
328332
let (
329333
mut names,
330334
mut unix_socket_list,
@@ -343,6 +347,7 @@ mod linux {
343347
NameSpace::File => handle_file_namespace(
344348
name,
345349
mount,
350+
named_files,
346351
&mut mount_list,
347352
&mut inode_list,
348353
&mut device_list,
@@ -1087,7 +1092,8 @@ mod linux {
10871092
/// # Arguments
10881093
///
10891094
/// * `names` - A mutable reference to a `Names` object containing the file path.
1090-
/// * `mount` - A boolean indicating whether to handle mount information or not.
1095+
/// * `mount` - A boolean indicating whether to handle mount information or not (-c flag).
1096+
/// * `named_files` - A boolean indicating report only for named files (-f flag).
10911097
/// * `mount_list` - A mutable reference to a `MountList` for reading mount points.
10921098
/// * `inode_list` - A mutable reference to an `InodeList` for updating inode information.
10931099
/// * `device_list` - A mutable reference to a `DeviceList` for updating device information.
@@ -1102,6 +1108,7 @@ mod linux {
11021108
fn handle_file_namespace(
11031109
names: &mut Names,
11041110
mount: bool,
1111+
named_files: bool,
11051112
mount_list: &mut MountList,
11061113
inode_list: &mut InodeList,
11071114
device_list: &mut DeviceList,
@@ -1112,7 +1119,14 @@ mod linux {
11121119
let st = timeout(&names.filename.to_string_lossy(), 5)?;
11131120
read_proc_mounts(mount_list)?;
11141121

1115-
if mount {
1122+
// POSIX: For block special devices, all processes using any file on
1123+
// that device are listed (unless -f is specified).
1124+
// -c (mount): Treat file as mount point, report on any files in filesystem.
1125+
// -f (named_files): Report only for the named files.
1126+
let is_block_device = (st.mode() & libc::S_IFMT) == libc::S_IFBLK;
1127+
let use_device_mode = mount || (is_block_device && !named_files);
1128+
1129+
if use_device_mode {
11161130
*device_list = DeviceList::new(names.clone(), st.dev());
11171131
*need_check_map = true;
11181132
} else {
@@ -1302,6 +1316,7 @@ mod macos {
13021316
pub fn get_matched_procs(
13031317
file: Vec<PathBuf>,
13041318
mount: bool,
1319+
named_files: bool,
13051320
) -> Result<Vec<Names>, Box<dyn std::error::Error>> {
13061321
let mut names: Vec<Names> = file
13071322
.iter()
@@ -1312,10 +1327,17 @@ mod macos {
13121327
let st = timeout(&name.filename.to_string_lossy(), 5)?;
13131328
let uid = st.uid();
13141329

1330+
// POSIX: For block special devices, all processes using any file on
1331+
// that device are listed (unless -f is specified).
1332+
// -c (mount): Treat file as mount point, report on any files in filesystem.
1333+
// -f (named_files): Report only for the named files.
1334+
let is_block_device = (st.mode() & libc::S_IFMT) == libc::S_IFBLK;
1335+
let is_volume = mount || (is_block_device && !named_files);
1336+
13151337
let pids = listpidspath(
13161338
osx_libproc_bindings::PROC_ALL_PIDS,
13171339
Path::new(&name.filename),
1318-
mount,
1340+
is_volume,
13191341
false,
13201342
)?;
13211343

@@ -1416,17 +1438,19 @@ fn print_matches(name: &mut Names, user: bool) -> Result<(), io::Error> {
14161438

14171439
eprint!("{}", access);
14181440
if user {
1419-
let owner = unsafe {
1441+
let owner_str: String = unsafe {
14201442
let pw_entry = libc::getpwuid(uid);
14211443
if pw_entry.is_null() {
1422-
"unknownr"
1444+
// POSIX: if user name cannot be resolved, print the real user ID
1445+
uid.to_string()
14231446
} else {
14241447
CStr::from_ptr((*pw_entry).pw_name)
14251448
.to_str()
1426-
.unwrap_or("invalid_string")
1449+
.unwrap_or(&uid.to_string())
1450+
.to_string()
14271451
}
14281452
};
1429-
eprint!("({})", owner);
1453+
eprint!("({})", owner_str);
14301454
}
14311455
io::stderr().flush()?;
14321456
}
@@ -1480,7 +1504,10 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
14801504
bind_textdomain_codeset("posixutils-rs", "UTF-8")?;
14811505

14821506
let Args {
1483-
mount, user, file, ..
1507+
mount,
1508+
named_files,
1509+
user,
1510+
file,
14841511
} = Args::try_parse().unwrap_or_else(|err| match err.kind() {
14851512
clap::error::ErrorKind::DisplayHelp | clap::error::ErrorKind::DisplayVersion => {
14861513
print!("{err}");
@@ -1496,10 +1523,10 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
14961523
});
14971524

14981525
#[cfg(target_os = "linux")]
1499-
let mut names = linux::get_matched_procs(file, mount)?;
1526+
let mut names = linux::get_matched_procs(file, mount, named_files)?;
15001527

15011528
#[cfg(target_os = "macos")]
1502-
let mut names = macos::get_matched_procs(file, mount)?;
1529+
let mut names = macos::get_matched_procs(file, mount, named_files)?;
15031530

15041531
for name in names.iter_mut() {
15051532
print_matches(name, user)?;

0 commit comments

Comments
 (0)