Skip to content

Commit cb833df

Browse files
oech3cakebaker
authored andcommitted
uucore: remove unsafe get_groups
1 parent 7a83db4 commit cb833df

1 file changed

Lines changed: 9 additions & 40 deletions

File tree

src/uucore/src/lib/features/entries.rs

Lines changed: 9 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535
#[cfg(any(target_os = "freebsd", target_vendor = "apple"))]
3636
use libc::time_t;
3737
use libc::{c_char, c_int, gid_t, uid_t};
38-
use libc::{getgrgid, getgrnam, getgroups};
38+
use libc::{getgrgid, getgrnam};
3939
use libc::{getpwnam, getpwuid, group, passwd};
4040

4141
use std::ffi::{CStr, CString};
@@ -57,42 +57,6 @@ unsafe extern "C" {
5757
) -> c_int;
5858
}
5959

60-
/// From: `<https://man7.org/linux/man-pages/man2/getgroups.2.html>`
61-
/// > getgroups() returns the supplementary group IDs of the calling
62-
/// > process in list.
63-
/// > If size is zero, list is not modified, but the total number of
64-
/// > supplementary group IDs for the process is returned. This allows
65-
/// > the caller to determine the size of a dynamically allocated list
66-
/// > to be used in a further call to getgroups().
67-
pub fn get_groups() -> IOResult<Vec<gid_t>> {
68-
let mut groups = Vec::new();
69-
loop {
70-
let ngroups = match unsafe { getgroups(0, ptr::null_mut()) } {
71-
-1 => return Err(IOError::last_os_error()),
72-
// Not just optimization; 0 would mess up the next call
73-
0 => return Ok(Vec::new()),
74-
n => n,
75-
};
76-
77-
// This is a small buffer, so we can afford to zero-initialize it and
78-
// use safe Vec operations
79-
groups.resize(ngroups.try_into().unwrap(), 0);
80-
let res = unsafe { getgroups(ngroups, groups.as_mut_ptr()) };
81-
if res == -1 {
82-
let err = IOError::last_os_error();
83-
if err.raw_os_error() == Some(libc::EINVAL) {
84-
// Number of groups has increased, retry
85-
} else {
86-
return Err(err);
87-
}
88-
} else {
89-
// Number of groups may have decreased
90-
groups.truncate(res.try_into().unwrap());
91-
return Ok(groups);
92-
}
93-
}
94-
}
95-
9660
/// The list of group IDs returned from GNU's `groups` and GNU's `id --groups`
9761
/// starts with the effective group ID (egid).
9862
/// This is a wrapper for `get_groups()` to mimic this behavior.
@@ -116,8 +80,9 @@ pub fn get_groups() -> IOResult<Vec<gid_t>> {
11680
/// > history of a process and its parents could affect the details of
11781
/// > the result.)
11882
#[cfg(all(unix, not(target_os = "redox"), feature = "process"))]
119-
pub fn get_groups_gnu(arg_id: Option<u32>) -> IOResult<Vec<gid_t>> {
120-
let groups = get_groups()?;
83+
pub fn get_groups_gnu(arg_id: Option<u32>) -> IOResult<Vec<rustix::process::RawGid>> {
84+
let groups = rustix::process::getgroups()
85+
.map(|g| g.into_iter().map(rustix::fs::Gid::as_raw).collect())?;
12186
let egid = arg_id.unwrap_or_else(crate::features::process::getegid);
12287
Ok(sort_groups(groups, egid))
12388
}
@@ -383,7 +348,11 @@ mod test {
383348

384349
#[test]
385350
fn test_entries_get_groups_gnu() {
386-
if let Ok(mut groups) = get_groups() {
351+
if let Ok(mut groups) = rustix::process::getgroups().map(|g| {
352+
g.into_iter()
353+
.map(rustix::fs::Gid::as_raw)
354+
.collect::<Vec<_>>()
355+
}) {
387356
if let Some(last) = groups.pop() {
388357
groups.insert(0, last);
389358
assert_eq!(get_groups_gnu(Some(last)).unwrap(), groups);

0 commit comments

Comments
 (0)