This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: FD_SET and FORTIFY_SOURCE


(2/28/13 11:24 AM), Florian Weimer wrote:
> On 02/28/2013 02:41 PM, Rich Felker wrote:
>> The problem is that a large amount of otherwise-correct software uses
>> malloc and out-of-bounds FD_SET arguments to work with sets larger
>> than FD_SETSIZE. I have written on the issue before that the "correct"
>> way to do this is allocate an array of fd_set objects and use / and %
>> to address the bit rather than passing an out-of-bounds argument to
>> FD_SET (which invokes UB), but some important software like libevent
>> (if I remember correctly) remains wrong in this regard.
> 
> The order of bits is unspecified.  The fd_set elements are typically 
> words, not bytes, and the bit order of the two access patterns differs 
> on big-endian machines.  (I believe this has been used as an argument 
> that little-endian is the natural order, the Internet not withstanding.) 
>   I can't believe that your kludge is actually more portable than just 
> requiring poll support. 8-)


The gentle way is to use howmany()+NFDBITS macro. This works on Linux, *BSD, Solaris,
HP-UX, and other many UNIX.
Even though it is unspecified behavior form POSIX POV, it is enough portable in practice.

I think current __FD_ELT is right implemenation. It only fail when passed argument is not
dynamic allocated.


cut-n-paste from sudo
----------------
   fdsr = ecalloc(howmany(maxfd + 1, NFDBITS), sizeof(fd_mask));
    memset(&cstat, 0, sizeof(cstat));
    tv.tv_sec = 0;
    tv.tv_usec = 0;
    for (;;) {
	/* Check for signal on backchannel or errno on errpipe. */
	FD_SET(backchannel, fdsr);
	FD_SET(signal_pipe[0], fdsr);
	if (errpipe[0] != -1)
	    FD_SET(errpipe[0], fdsr);
	maxfd = MAX(MAX(errpipe[0], signal_pipe[0]), backchannel);

	/* If command exited we just poll, there may be data on errpipe. */
	n = select(maxfd + 1, fdsr, NULL, NULL, alive ? NULL : &tv);



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]