Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion src/backend/libc/fs/syscalls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1478,12 +1478,17 @@ pub(crate) fn fchown(fd: BorrowedFd<'_>, owner: Option<Uid>, group: Option<Gid>)
// implementations, such as musl, add extra logic to `fchown` to emulate
// support for `O_PATH`, which uses `/proc` outside our control and
// interferes with our own use of `O_PATH`.
#[cfg(any(target_arch = "x86", target_arch = "arm", target_arch = "sparc"))]
const SYS: c::c_long = c::SYS_fchown32 as c::c_long;
#[cfg(not(any(target_arch = "x86", target_arch = "arm", target_arch = "sparc")))]
const SYS: c::c_long = c::SYS_fchown as c::c_long;

syscall! {
fn fchown(
fd: c::c_int,
owner: c::uid_t,
group: c::gid_t
) via SYS_fchown -> c::c_int
) via SYS -> c::c_int
}
unsafe {
let (ow, gr) = crate::ugid::translate_fchown_args(owner, group);
Expand Down
21 changes: 18 additions & 3 deletions src/backend/libc/thread/syscalls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -389,8 +389,13 @@ pub(crate) fn capset(
#[cfg(linux_kernel)]
#[inline]
pub(crate) fn setuid_thread(uid: crate::ugid::Uid) -> io::Result<()> {
#[cfg(any(target_arch = "x86", target_arch = "arm", target_arch = "sparc"))]
const SYS: c::c_long = c::SYS_setuid32 as c::c_long;
#[cfg(not(any(target_arch = "x86", target_arch = "arm", target_arch = "sparc")))]
const SYS: c::c_long = c::SYS_setuid as c::c_long;

syscall! {
fn setuid(uid: c::uid_t) via SYS_setuid -> c::c_int
fn setuid(uid: c::uid_t) via SYS -> c::c_int
}

unsafe { ret(setuid(uid.as_raw())) }
Expand Down Expand Up @@ -424,8 +429,13 @@ pub(crate) fn setresuid_thread(
#[cfg(linux_kernel)]
#[inline]
pub(crate) fn setgid_thread(gid: crate::ugid::Gid) -> io::Result<()> {
#[cfg(any(target_arch = "x86", target_arch = "arm", target_arch = "sparc"))]
const SYS: c::c_long = c::SYS_setgid32 as c::c_long;
#[cfg(not(any(target_arch = "x86", target_arch = "arm", target_arch = "sparc")))]
const SYS: c::c_long = c::SYS_setgid as c::c_long;

syscall! {
fn setgid(gid: c::gid_t) via SYS_setgid -> c::c_int
fn setgid(gid: c::gid_t) via SYS -> c::c_int
}

unsafe { ret(setgid(gid.as_raw())) }
Expand Down Expand Up @@ -696,8 +706,13 @@ pub(crate) fn futex_waitv(
#[cfg(linux_kernel)]
#[inline]
pub(crate) fn setgroups_thread(groups: &[crate::ugid::Gid]) -> io::Result<()> {
#[cfg(any(target_arch = "x86", target_arch = "arm", target_arch = "sparc"))]
const SYS: c::c_long = c::SYS_setgroups32 as c::c_long;
#[cfg(not(any(target_arch = "x86", target_arch = "arm", target_arch = "sparc")))]
const SYS: c::c_long = c::SYS_setgroups as c::c_long;

syscall! {
fn setgroups(size: c::size_t, list: *const c::gid_t) via SYS_setgroups -> c::c_int
fn setgroups(size: c::size_t, list: *const c::gid_t) via SYS -> c::c_int
}
ret(unsafe { setgroups(groups.len(), groups.as_ptr().cast()) })
}
Expand Down
25 changes: 24 additions & 1 deletion src/backend/linux_raw/fs/syscalls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -164,8 +164,25 @@ pub(crate) fn chownat(

#[inline]
pub(crate) fn chown(path: &CStr, owner: Option<Uid>, group: Option<Gid>) -> io::Result<()> {
#[cfg(any(target_arch = "arm", target_arch = "sparc", target_arch = "x86"))]
unsafe {
let (ow, gr) = crate::ugid::translate_fchown_args(owner, group);
ret(syscall_readonly!(
__NR_chown32,
path,
c_uint(ow),
c_uint(gr)
))
}

// Most architectures have a `chown` syscall.
#[cfg(not(any(target_arch = "aarch64", target_arch = "riscv64")))]
#[cfg(not(any(
target_arch = "aarch64",
target_arch = "arm",
target_arch = "riscv64",
target_arch = "sparc",
target_arch = "x86"
)))]
unsafe {
let (ow, gr) = crate::ugid::translate_fchown_args(owner, group);
ret(syscall_readonly!(__NR_chown, path, c_uint(ow), c_uint(gr)))
Expand All @@ -188,6 +205,12 @@ pub(crate) fn chown(path: &CStr, owner: Option<Uid>, group: Option<Gid>) -> io::

#[inline]
pub(crate) fn fchown(fd: BorrowedFd<'_>, owner: Option<Uid>, group: Option<Gid>) -> io::Result<()> {
#[cfg(any(target_arch = "arm", target_arch = "sparc", target_arch = "x86"))]
unsafe {
let (ow, gr) = crate::ugid::translate_fchown_args(owner, group);
ret(syscall_readonly!(__NR_fchown32, fd, c_uint(ow), c_uint(gr)))
}
#[cfg(not(any(target_arch = "arm", target_arch = "sparc", target_arch = "x86")))]
unsafe {
let (ow, gr) = crate::ugid::translate_fchown_args(owner, group);
ret(syscall_readonly!(__NR_fchown, fd, c_uint(ow), c_uint(gr)))
Expand Down
9 changes: 9 additions & 0 deletions src/backend/linux_raw/process/syscalls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -519,6 +519,15 @@ pub(crate) fn pivot_root(new_root: &CStr, put_old: &CStr) -> io::Result<()> {
pub(crate) fn getgroups(buf: &mut [Gid]) -> io::Result<usize> {
let len = buf.len().try_into().map_err(|_| io::Errno::NOMEM)?;

#[cfg(any(target_arch = "arm", target_arch = "sparc", target_arch = "x86"))]
unsafe {
ret_usize(syscall!(
__NR_getgroups32,
c_int(len),
slice_just_addr_mut(buf)
))
}
#[cfg(not(any(target_arch = "arm", target_arch = "sparc", target_arch = "x86")))]
unsafe {
ret_usize(syscall!(
__NR_getgroups,
Expand Down
27 changes: 24 additions & 3 deletions src/backend/linux_raw/thread/syscalls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -400,7 +400,14 @@ pub(crate) fn capset(

#[inline]
pub(crate) fn setuid_thread(uid: crate::ugid::Uid) -> io::Result<()> {
unsafe { ret(syscall_readonly!(__NR_setuid, uid)) }
#[cfg(any(target_arch = "x86", target_arch = "arm", target_arch = "sparc"))]
unsafe {
ret(syscall_readonly!(__NR_setuid32, uid))
}
#[cfg(not(any(target_arch = "x86", target_arch = "arm", target_arch = "sparc")))]
unsafe {
ret(syscall_readonly!(__NR_setuid, uid))
}
}

#[inline]
Expand All @@ -421,7 +428,14 @@ pub(crate) fn setresuid_thread(

#[inline]
pub(crate) fn setgid_thread(gid: crate::ugid::Gid) -> io::Result<()> {
unsafe { ret(syscall_readonly!(__NR_setgid, gid)) }
#[cfg(any(target_arch = "x86", target_arch = "arm", target_arch = "sparc"))]
unsafe {
ret(syscall_readonly!(__NR_setgid32, gid))
}
#[cfg(not(any(target_arch = "x86", target_arch = "arm", target_arch = "sparc")))]
unsafe {
ret(syscall_readonly!(__NR_setgid, gid))
}
}

#[inline]
Expand All @@ -443,7 +457,14 @@ pub(crate) fn setresgid_thread(
#[inline]
pub(crate) fn setgroups_thread(gids: &[crate::ugid::Gid]) -> io::Result<()> {
let (addr, len) = slice(gids);
unsafe { ret(syscall_readonly!(__NR_setgroups, len, addr)) }
#[cfg(any(target_arch = "x86", target_arch = "arm", target_arch = "sparc"))]
unsafe {
ret(syscall_readonly!(__NR_setgroups32, len, addr))
}
#[cfg(not(any(target_arch = "x86", target_arch = "arm", target_arch = "sparc")))]
unsafe {
ret(syscall_readonly!(__NR_setgroups, len, addr))
}
}

// `sched_getcpu` has special optimizations via the vDSO on some architectures.
Expand Down
17 changes: 17 additions & 0 deletions tests/process/id.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,23 @@ fn test_getegid() {
}
}

#[cfg(feature = "alloc")]
#[test]
fn test_getgroups() {
let groups = process::getgroups().unwrap();
assert_eq!(groups, process::getgroups().unwrap());
unsafe {
let ngroups = libc::getgroups(0, core::ptr::null_mut());
assert!(ngroups >= 0);
let mut libc_groups = vec![0 as libc::gid_t; ngroups as usize];
if ngroups > 0 {
assert_eq!(libc::getgroups(ngroups, libc_groups.as_mut_ptr()), ngroups);
}
let raw_groups: Vec<libc::gid_t> = groups.iter().map(|g| g.as_raw()).collect();
assert_eq!(raw_groups, libc_groups);
}
}

#[test]
fn test_getpid() {
assert_eq!(process::getpid(), process::getpid());
Expand Down
Loading