Red Hat Bugzilla – Bug 77488
FD_SET macro silently corrupt memeory
Last modified: 2007-04-18 12:48:13 EDT
From Bugzilla Helper:
User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.0.1) Gecko/20021003
Description of problem:
When using a lot of file descriptors with select it is very easy to exceed the
number of file descriptors possible within FD_SETSIZE. If you try to use the
FD_SET macro on a file descriptor which is greater than FD_SETSIZE then it
silently corrupts other memory. A check should be added to FD_SET to make sure
that it doesn't use a file descriptor which can corrupt memory.
Version-Release number of selected component (if applicable):
Steps to Reproduce:
1. make a program that opens 1025 files.
2. try to select on the 1025th file.
3. notice how other variables in the program are corrupted.
Actual Results: corrupted memory
Expected Results: An error from FD_SET or an assert or a message on stderr or
From: Morris Jette <firstname.lastname@example.org>
Subject: Request for Linux update
Date: 07 Nov 2002 11:56:21 -0800
I just spent a couple of days finding a bug that I tranced to
an undocumented feature of the select function that needs to
be documented if not fixed in the function.
If one goes over FD_SETSIZE in the select data structures,
memory gets silently corrupted. This needs to be *at least*
documented in the select man page. A better solution would
be to have the functions which manipulate the data structure
perform a range check, but that would involve some additional
overhead (worthwhile overhead I would say based upon my
Morris "Moe" Jette email@example.com 925-423-4856
Integrated Computational Resource Management Group fax 925-423-8719
Livermore Computing Lawrence Livermore National Laboratory
Work around is to use poll.
At the very least this should be documented in the man page.
The only reasonable solution that I've come up with so far and I don't know if
this is doable is to have FD_SET intentionally corrupt the fdset in such a way
that all subsequent fd_set operations fail and when it is passed into select,
select returns with an errno.
There is nothing to change in glibc for this. Use poll and be happy.
Although this is not documented in the man page, it is documented in standards, e.g.
The behaviour of these macros is undefined if the fd argument is less than 0 or greater than or equal to FD_SETSIZE, or
if any of the arguments are expressions with side effects.
and also in glibc documentation - info libc says:
- Macro: int FD_SETSIZE
The value of this macro is the maximum number of file descriptors
that a `fd_set' object can hold information about. On systems
with a fixed maximum number, `FD_SETSIZE' is at least that number.
On some systems, including GNU, there is no absolute limit on the
number of descriptors open, but this macro still has a constant
value which controls the number of bits in an `fd_set'; if you get
a file descriptor with a value as high as `FD_SETSIZE', you cannot
put that descriptor into an `fd_set'.
- Macro: void FD_ZERO (fd_set *SET)
This macro initializes the file descriptor set SET to be the empty
- Macro: void FD_SET (int FILEDES, fd_set *SET)
This macro adds FILEDES to the file descriptor set SET.
- Macro: void FD_CLR (int FILEDES, fd_set *SET)
This macro removes FILEDES from the file descriptor set SET.
- Macro: int FD_ISSET (int FILEDES, fd_set *SET)
This macro returns a nonzero value (true) if FILEDES is a member
of the file descriptor set SET, and zero (false) otherwise.
this is now noted in the current select man pages --> closing BZ