Skip to content

posixsubprocess: call libc setgroups directly in the child - #8609

Merged
youknowone merged 1 commit into
RustPython:mainfrom
youknowone:host-env-setgroups-macos
Aug 30, 2026
Merged

youknowone merged 1 commit into
RustPython:mainfrom
youknowone:host-env-setgroups-macos

Conversation

@youknowone

@youknowone youknowone commented Aug 29, 2026 •

Copy link
Copy Markdown
Member

setgroups_if_needed carried target_os = "macos" in its cfg(not(any(...))), so on macOS the extra_groups argument was accepted by _posixsubprocess.fork_exec and then silently dropped — the child ran with the parent's group list.

nix gates unistd::setgroups off apple_targets, redox and haiku, which is where that exclusion came from. libc declares setgroups on every one of those except redox, so this calls it directly and checks the return with nix::Error::result — the same shape the adjacent setregid_if_needed and setreuid_if_needed already use. ngroups is c_int on the BSDs and size_t on linux, hence as _.

Passing the caller's &[u32] straight through also drops an allocation: u32 and libc::gid_t have the same layout, so no Vec<Gid> needs to be built. That code runs in the child between fork and exec, where malloc is not async-signal-safe.

Draft: not yet exercised against test_subprocess's extra_groups cases on macOS, and iOS is still excluded.

— commented by Claude

Summary by CodeRabbit

  • Bug Fixes
    • Improved process group handling on macOS.
    • Reduced the risk of failures when configuring group IDs after process creation.
    • Preserved existing behavior on supported platforms while continuing to disable the operation on iOS and Redox.

`setgroups_if_needed` was compiled out on macOS, so `extra_groups` was
accepted and then silently ignored there.  nix gates `unistd::setgroups`
off `apple_targets`, `redox` and `haiku`; calling `libc::setgroups` and
checking the return with `nix::Error::result` is the shape the adjacent
`setregid_if_needed` and `setreuid_if_needed` already use, and libc
declares the function everywhere except redox.

`u32` and `libc::gid_t` have the same layout, so the caller's slice is
passed as-is instead of being collected into a fresh `Vec` after fork
and before exec.  `ngroups` is `c_int` on the BSDs and `size_t` on
linux, hence `as _`.

Assisted-by: Claude
@coderabbitai

coderabbitai Bot commented Aug 29, 2026 •

Copy link
Copy Markdown
Contributor

Review Change Stack

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro Plus

Run ID: 059059fa-e91a-4404-9836-7475889629a4

📥 Commits

Reviewing files that changed from the base of the PR and between 371bb82 and 03cb7f6.

📒 Files selected for processing (1)
  • crates/host_env/src/posix.rs

📝 Walkthrough

Walkthrough

setgroups_if_needed now passes the caller-provided group IDs directly to libc without allocating a Vec. The operation is enabled on macOS and remains disabled on iOS and Redox.

Changes

POSIX group setup

Layer / File(s) Summary
Direct libc group setup
crates/host_env/src/posix.rs
setgroups_if_needed uses the provided group slice directly, calls libc setgroups, and includes macOS among supported targets.

Estimated code review effort: 2 (Simple) | ~10 minutes

Suggested reviewers: joshuamegnauth54, luantaraschi

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@youknowone
youknowone marked this pull request as ready for review August 30, 2026 01:52
@youknowone
youknowone merged commit 1db2006 into RustPython:main Aug 30, 2026
27 of 28 checks passed
@youknowone
youknowone deleted the host-env-setgroups-macos branch August 30, 2026 01:52
youknowone added a commit that referenced this pull request Sep 16, 2026
`setgroups_if_needed` was compiled out on macOS, so `extra_groups` was
accepted and then silently ignored there.  nix gates `unistd::setgroups`
off `apple_targets`, `redox` and `haiku`; calling `libc::setgroups` and
checking the return with `nix::Error::result` is the shape the adjacent
`setregid_if_needed` and `setreuid_if_needed` already use, and libc
declares the function everywhere except redox.

`u32` and `libc::gid_t` have the same layout, so the caller's slice is
passed as-is instead of being collected into a fresh `Vec` after fork
and before exec.  `ngroups` is `c_int` on the BSDs and `size_t` on
linux, hence `as _`.

Assisted-by: Claude
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant