Skip to content

Fix sigaddset/sigdelset bit-fiddling math #23502

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 10, 2025
Merged

Conversation

rootbeer
Copy link
Contributor

@rootbeer rootbeer commented Apr 8, 2025

The code was using u32 and usize interchangably, which doesn't work on 64-bit systems. This: pub const sigset_t = [1024 / 32]u32; is not consistent with this: const shift = @as(u5, @intCast(s & (usize_bits - 1)));

However, normal signal numbers are less than 31, so the bad math doesn't matter much. Also, despite support for 1024 signals in the set, only setting signals between 1 and NSIG (which is mostly 65, but sometimes 128) is defined. The existing tests only exercised signal numbers in the first 31 bits so they didn't trigger the overflow.

The C library sigaddset will return EINVAL if given an out of bounds signal number. I made the Zig code just silently ignore any out of bounds signal numbers.

I moved all the sigset related declarations to be adjacent in the source, too.

The filled_sigset seems non-standard to me. I think it is meant to be used like empty_sigset, but it only contains 31 set signals, which seems wrong (should be 64 or 128, aka NSIG). It's also unused. The oddly named but similar all_mask is used (by posix.zig) but sets all 1024 bits (which I understood to be undefined behavior but seems to work just fine). For comparison the musl sigfillset only fills in 64 bits (or 128 bits).

@alexrp
Copy link
Member

alexrp commented Apr 8, 2025

The C library sigaddset will return EINVAL if given an out of bounds signal number. I made the Zig code just silently ignore any out of bounds signal numbers.

I feel like we should assert() here. This is clearly programmer error?

@rootbeer
Copy link
Contributor Author

rootbeer commented Apr 8, 2025

The C library sigaddset will return EINVAL if given an out of bounds signal number. I made the Zig code just silently ignore any out of bounds signal numbers.

I feel like we should assert() here. This is clearly programmer error?

Yeah, this is programmer error, and users are very likely to just be passing in SIG. constants. Done.

@alexrp alexrp self-assigned this Apr 9, 2025
Copy link
Member

@alexrp alexrp left a comment

Choose a reason for hiding this comment

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

Seems fine; the suggested cleanup above is optional since it's no worse than what was there already.

The code was using u32 and usize interchangably, which doesn't work on
64-bit systems.  This:
  `pub const sigset_t = [1024 / 32]u32;`
is not consistent with this:
  `const shift = @as(u5, @intcast(s & (usize_bits - 1)));`

However, normal signal numbers are less than 31, so the bad math doesn't matter much.  Also, despite support for 1024 signals in the set, only setting signals between 1 and NSIG (which is mostly 65, but sometimes 128) is defined.  The existing tests only exercised signal numbers in the first 31 bits so they didn't trip over this:

The C library `sigaddset` will return `EINVAL` if given an out of bounds signal number.  I made the Zig code just silently ignore any out of bounds signal numbers.

Moved all the `sigset` related declarations next to each in the source, too.

The `filled_sigset` seems non-standard to me.  I think it is meant to be used like `empty_sigset`, but it only contains 31 set signals, which seems wrong (should be 64 or 128, aka `NSIG`).  It's also unused.  The oddly named but similar `all_mask` is used (by posix.zig) but sets all 1024 bits (which I understood to be undefined behavior but seems to work just fine).  For comparison the musl `sigfillset` fills in 65 bits or 128 bits.
@alexrp alexrp enabled auto-merge (rebase) April 10, 2025 16:51
@alexrp alexrp merged commit 4b63f94 into ziglang:master Apr 10, 2025
9 checks passed
@alexrp alexrp removed their assignment Apr 11, 2025
@rootbeer rootbeer deleted the sigset branch April 11, 2025 04:08
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.

2 participants