Skip to content

Commit 2fc59e9

Browse files
authored
Add setgroups and fix getgroups (#1006)
1 parent b494d28 commit 2fc59e9

File tree

5 files changed

+35
-19
lines changed

5 files changed

+35
-19
lines changed

src/backend/libc/thread/syscalls.rs

+9
Original file line numberDiff line numberDiff line change
@@ -531,3 +531,12 @@ unsafe fn futex_old(
531531
val3,
532532
) as isize)
533533
}
534+
535+
#[cfg(linux_kernel)]
536+
#[inline]
537+
pub(crate) fn setgroups_thread(groups: &[crate::ugid::Gid]) -> io::Result<()> {
538+
syscall! {
539+
fn setgroups(size: c::size_t, list: *const c::gid_t) via SYS_setgroups -> c::c_int
540+
}
541+
ret(unsafe { setgroups(groups.len(), groups.as_ptr().cast()) })
542+
}

src/backend/linux_raw/thread/syscalls.rs

+7-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
use crate::backend::c;
99
use crate::backend::conv::{
10-
by_mut, by_ref, c_int, c_uint, ret, ret_c_int, ret_c_int_infallible, ret_usize,
10+
by_mut, by_ref, c_int, c_uint, ret, ret_c_int, ret_c_int_infallible, ret_usize, slice,
1111
slice_just_addr, slice_just_addr_mut, zero,
1212
};
1313
use crate::fd::BorrowedFd;
@@ -345,3 +345,9 @@ pub(crate) fn setresgid_thread(
345345
ret(syscall_readonly!(__NR_setresgid, rgid, egid, sgid))
346346
}
347347
}
348+
349+
#[inline]
350+
pub(crate) fn setgroups_thread(gids: &[crate::ugid::Gid]) -> io::Result<()> {
351+
let (addr, len) = slice(gids);
352+
unsafe { ret(syscall_readonly!(__NR_setgroups, len, addr)) }
353+
}

src/process/id.rs

+5-16
Original file line numberDiff line numberDiff line change
@@ -213,20 +213,9 @@ pub fn setsid() -> io::Result<Pid> {
213213
pub fn getgroups() -> io::Result<Vec<Gid>> {
214214
// This code would benefit from having a better way to read into
215215
// uninitialized memory, but that requires `unsafe`.
216-
let mut buffer = Vec::with_capacity(8);
217-
buffer.resize(buffer.capacity(), Gid::ROOT);
218-
219-
loop {
220-
let ngroups = backend::process::syscalls::getgroups(&mut buffer)?;
221-
222-
let ngroups = ngroups as usize;
223-
assert!(ngroups <= buffer.len());
224-
if ngroups < buffer.len() {
225-
buffer.resize(ngroups, Gid::ROOT);
226-
return Ok(buffer);
227-
}
228-
// Use `Vec` reallocation strategy to grow capacity exponentially.
229-
buffer.reserve(1);
230-
buffer.resize(buffer.capacity(), Gid::ROOT);
231-
}
216+
let mut buffer = Vec::with_capacity(0);
217+
let ngroups = backend::process::syscalls::getgroups(&mut buffer)?;
218+
buffer.resize(ngroups, Gid::ROOT);
219+
backend::process::syscalls::getgroups(&mut buffer)?;
220+
Ok(buffer)
232221
}

src/thread/id.rs

+12
Original file line numberDiff line numberDiff line change
@@ -113,3 +113,15 @@ pub fn set_thread_gid(gid: Gid) -> io::Result<()> {
113113
pub fn set_thread_res_gid(rgid: Gid, egid: Gid, sgid: Gid) -> io::Result<()> {
114114
backend::thread::syscalls::setresgid_thread(rgid, egid, sgid)
115115
}
116+
117+
/// `setgroups(groups)`-Sets the supplementary group IDs for the calling thread.
118+
///
119+
/// # References
120+
/// - [Linux]
121+
///
122+
/// [Linux]: https://man7.org/linux/man-pages/man2/setgroups.2.html
123+
#[cfg(linux_kernel)]
124+
#[inline]
125+
pub fn set_thread_groups(groups: &[Gid]) -> io::Result<()> {
126+
backend::thread::syscalls::setgroups_thread(groups)
127+
}

src/thread/mod.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@ pub use clock::*;
1919
pub use futex::{futex, FutexFlags, FutexOperation};
2020
#[cfg(linux_kernel)]
2121
pub use id::{
22-
gettid, set_thread_gid, set_thread_res_gid, set_thread_res_uid, set_thread_uid, Gid, Pid,
23-
RawGid, RawPid, RawUid, Uid,
22+
gettid, set_thread_gid, set_thread_groups, set_thread_res_gid, set_thread_res_uid,
23+
set_thread_uid, Gid, Pid, RawGid, RawPid, RawUid, Uid,
2424
};
2525
#[cfg(linux_kernel)]
2626
pub use libcap::{capabilities, set_capabilities, CapabilityFlags, CapabilitySets};

0 commit comments

Comments
 (0)