Skip to content

fix(sandbox): zero-initialize sigset_t before assume_init - #5194

Merged
FrostGod merged 1 commit into
NVIDIA:mainfrom
EmilienM:fix/5187-zero-init-sigset/EmilienM
Nov 5, 2026
Merged

FrostGod merged 1 commit into
NVIDIA:mainfrom
EmilienM:fix/5187-zero-init-sigset/EmilienM

Conversation

@EmilienM

@EmilienM EmilienM commented Nov 3, 2026 •

Copy link
Copy Markdown
Contributor

Summary

block_launcher_signals and install_child_signal_mask now build their libc::sigset_t from MaybeUninit::zeroed() instead of uninit(). On 64-bit musl, sigfillset and sigemptyset write only the first word of the 128-byte sigset_t, so assume_init() was reading uninitialized bytes. The mask handed to the kernel is unchanged; this removes the undefined behavior and fixes the SAFETY comments that claimed the libc calls fully initialized the value.

Related Issue

Closes #5187
Part of #5179

Note for maintainers: #5187 still needs state:accepted for the PR Issue Acceptance check to pass.

Changes

  • block_launcher_signals and install_child_signal_mask use MaybeUninit::zeroed()
  • Corrected the // SAFETY: comments on both assume_init() calls
  • Added tests that call both functions, assert the resulting mask state, and restore the previous mask
  • Kept the direct libc fix rather than moving to nix's SigSet::all()/empty(): nix's own constructors hold the same uninit + assume_init pattern this PR removes

Release Notes

Testing

  • cargo fmt --check -p openshell-sandbox
  • cargo clippy -p openshell-sandbox --all-targets -- -D warnings
  • cargo test -p openshell-sandbox (new tests pass; one lib test flakes under full parallelism on this host and also fails on clean main)
  • mise run e2e:podman:ci (sandbox image built from this tree, musl target)
  • The new tests are behavior checks for the mask operations (block, clear, restore); they cannot detect the uninitialized read itself, which is what the zeroed() initialization fixes. Miri cannot run this crate (FFI, seccomp, tokio).

Checklist

  • Follows Conventional Commits
  • Commits are signed off (DCO)
  • Architecture docs updated (not applicable)

@copy-pr-bot

copy-pr-bot Bot commented Nov 3, 2026

Copy link
Copy Markdown

This pull request requires additional validation before any workflows can run on NVIDIA's runners.

Pull request vetters can view their responsibilities here.

Contributors can view more details about this message here.

@FrostGod

FrostGod commented Nov 3, 2026

Copy link
Copy Markdown
Collaborator

/ok to test 3eeab41

@FrostGod

FrostGod commented Nov 4, 2026 •

Copy link
Copy Markdown
Collaborator

Not too familiar with section of the code but anyways, AI comment

The new tests verify signal behavior, but don’t detect the original uninitialized-memory bug. Please describe them as behavior checks rather than Miri-equivalent checks.

just verify we are not introducing any regression with this

@EmilienM

EmilienM commented Nov 4, 2026

Copy link
Copy Markdown
Contributor Author

Fair point, reworded: the tests are behavior checks for the mask operations (block, clear, restore), not a detector for the uninitialized read itself. Miri can't run this crate (FFI, seccomp, tokio), that's all.

No regressions that I can find: everything is green since your /ok to test, rust tests on all three triples included, plus the podman CI e2e I ran locally before opening. The only red is the advisory compatibility review, which failed with its own RuntimeError before producing an assessment, so there's nothing to act on there.

@mrunalp mrunalp added area:sandbox Sandbox runtime and isolation work test:e2e Requires end-to-end coverage labels Nov 4, 2026
@github-actions

github-actions Bot commented Nov 4, 2026

Copy link
Copy Markdown

Label test:e2e applied for 3eeab41. Open the existing run and click Re-run all jobs to execute with the label set. The run will execute the standard E2E suite after building the required gateway, sandbox, and supervisor images once. The matching required CI gate status on this PR will flip green automatically once the run finishes.

@mrunalp

mrunalp commented Nov 4, 2026

Copy link
Copy Markdown
Collaborator

/ok to test 3eeab41

@FrostGod FrostGod left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@FrostGod
FrostGod enabled auto-merge November 4, 2026 21:46
musl's sigfillset and sigemptyset write only the first word of the
128-byte sigset_t on x86_64 and aarch64, so assuming the MaybeUninit
value is initialized reads 120 uninitialized bytes in
block_launcher_signals and install_child_signal_mask. Start both from
MaybeUninit::zeroed() so the whole value is defined regardless of how
much the libc writes, and correct the SAFETY comments accordingly. An
all-zero sigset_t is a valid empty set, so the mask handed to the kernel
is unchanged. The nix SigSet constructors were rejected as an
alternative because they hold the same uninit + assume_init pattern.

Adds tests that call both functions on their own thread, assert the
resulting mask state, and restore the previous mask afterwards, since
Miri cannot run this crate's FFI and seccomp-heavy tests.

Closes NVIDIA#5187

Signed-off-by: Emilien Macchi <emacchi@redhat.com>
auto-merge was automatically disabled November 5, 2026 02:10

Head branch was pushed to by a user without write access

@EmilienM
EmilienM force-pushed the fix/5187-zero-init-sigset/EmilienM branch from 3eeab41 to b07594e Compare November 5, 2026 02:10
@FrostGod
FrostGod enabled auto-merge November 5, 2026 06:15
@FrostGod

FrostGod commented Nov 5, 2026

Copy link
Copy Markdown
Collaborator

/ok to test b07594e

@FrostGod
FrostGod added this pull request to the merge queue Nov 5, 2026
Merged via the queue into NVIDIA:main with commit 3564fdf Nov 5, 2026
257 of 269 checks passed
@FrostGod
FrostGod deleted the fix/5187-zero-init-sigset/EmilienM branch November 5, 2026 07:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:sandbox Sandbox runtime and isolation work test:e2e Requires end-to-end coverage

Projects

None yet

Development

Successfully merging this pull request may close these issues.

bug: sigset_t is only partly initialized under musl before assume_init

3 participants