Skip to content

linux: Improve panic message for out-of-range fds in FD_* functions - #5528

Open
danielcanencia wants to merge 1 commit into
rust-lang:mainfrom
danielcanencia:I_1401
Open

danielcanencia wants to merge 1 commit into
rust-lang:mainfrom
danielcanencia:I_1401

Conversation

@danielcanencia

@danielcanencia danielcanencia commented Sep 13, 2026

Copy link
Copy Markdown

Part of #1401

Fixes the out-of-bounds FD_SET/FD_CLR/FD_ISSET panic for Linux
(linux_like). The issue also calls for the same clear panic message in
other platforms; those remain a follow-up (cygwin, haiku, solaris, etc).

Note:

  • FD_ZERO needs no change — it takes no fd and fills the set, so there
    is nothing to range-check.

Passing a file descriptor that is negative or >= FD_SETSIZE to FD_SET,
FD_CLR or FD_ISSET is undefined behavior per POSIX, and the previous
"index out of bounds" panic gave no hint of the required range. Panic
with a message that states the valid 0..FD_SETSIZE range instead.

Source:
https://github.com/bminor/glibc/blob/d2097651cc57834dbfcaa102ddfacae0d86cfb66/misc/sys/select.h

Part of rust-lang#1401

Signed-off-by: Daniel Canencia Garcia <danielcanenciagarcia@gmail.com>

@tgross35 tgross35 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks for putting this together!

The issue also calls for the same clear panic message in other platforms; those remain a follow-up (cygwin, haiku, solaris, etc).

I'd prefer to get them all done at the same time.

View changes since this review

Comment on lines -1850 to +1852
(*set).fds_bits[fd / size] &= !(1 << (fd % size));
return;
*(*set).fds_bits.get_mut(fd / size).unwrap_or_else(|| {
core::panic!("fd {fd} out of range: valid fds are 0..FD_SETSIZE (0..{FD_SETSIZE})")
}) &= !(1 << (fd % size));

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This is tough to read, use let Some(...) = ... else { ... } instead

(*set).fds_bits[fd / size] &= !(1 << (fd % size));
return;
*(*set).fds_bits.get_mut(fd / size).unwrap_or_else(|| {
core::panic!("fd {fd} out of range: valid fds are 0..FD_SETSIZE (0..{FD_SETSIZE})")

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Add panic! to the prelude (update the macro_rules! prelude)

@@ -1847,21 +1847,26 @@ f! {
pub unsafe fn FD_CLR(fd: c_int, set: *mut fd_set) -> () {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Could you please update these functions everywhere they exist? They exist in a lot of modules, not just Linux.

@rustbot

rustbot commented Sep 15, 2026

Copy link
Copy Markdown
Collaborator

Reminder, once the PR becomes ready for a review, use @rustbot ready.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants