cURL / Mailing Lists / curl-library / Single Mail

curl-library

Re: yangtse: curl/tests/libtest lib518.c,1.23,1.24 lib537.c,1.8,1.9

From: Yang Tse <yangsita_at_gmail.com>
Date: Thu, 1 Feb 2007 15:29:34 +0100

Daniel Stenberg wrote:

> Do note that there's nothing that says file descriptor numbers must be lower
> than FD_SETSIZE AFAIK. I'm quite sure windows for example has file descriptors
> above FD_SETSIZE without supporting more than FD_SETSIZE number of descriptors
> in one select().

Well, probably the description was too short or misleading. In the
source code it is better commented and probably makes more sense.

Let me start saying that tests 518 and 537 won't be skipped if any of
HAVE_POLL_FINE, CURL_HAVE_WSAPOLL, USE_WINSOCK or TPF are defined. So
the test will still run on any platform that uses Winsock and on TPF
and on any platform that has a 'fine poll()' as per configure results
or specific platform configuration file.

As a matter of fact the check to see if the test is going to be
skipped or not is done in the precheck rlimit() function. So actually
the libtest code is being executed, and rlimit is the one which finds
out, or at least it tries its best, to know beforehand if the 'real'
test is going to fail on platforms which are not using Winsock and are
not TPF and are using select() instead of poll(), skipping the tests
only if none of the above defines are defined and any of the following
two conditions are met.

Condition 1) In the precheck phase rlimit() has been able to open more
than FD_SETSIZE file descriptors. This implies that when libcurl
creates a new socket the new socket number is going to be above
FD_SETSIZE for sure. So the VERIFY_SOCK macro in lib/select.c will
force Curl_select to fail returning -1, setting errno EINVAL and not
actually performing the call to the system select(). When performing
the 'real' test this condition would be again true and no matter how
many times we would allow libcurl to retry the Curl_select() call the
result would always be the same resulting in the test failure. This
applies both to test518 and test537.

The previous condition is checked before the next second one. The next
condition is most important to test537 since I think it is already
included in the previous condition for test518.

Condition 2) In the precheck phase rlimit() has NOT been able to open
more than FD_SETSIZE file descriptors. But at least one of them has a
number greater than FD_SETSIZE. This implies that when libcurl creates
a new socket the new socket number is QUITE LIKELY going to be above
FD_SETSIZE. So the VERIFY_SOCK macro in lib/select.c will force
Curl_select to fail returning -1, setting errno EINVAL and not
actually performing the call to the system select(). When performing
the 'real' test this condition would LIKELY be again true and then the
Curl_select() call would fail resulting in the test failure. This can
happen if the 'open file' system limit is below FD_SETSIZE.

Maybe all this is an oversimplification but the FD_SETSIZE issue,
might not only be within select() but also with macros FD_SET FD_xxx.

If anyone has some free time maybe could look into how to provide an
enhanced check that at configuration phase detects if the FD_xxx
macros and select() work with a socket number higher that FD_SETSIZE,
taking in account that when these fail due to FD_SETSIZE issues the
results can range from a 'simple' buffer overflow up to a 'nice'
program crash.

I've run out of better ideas related with this, so if anyone has a
better check for a valid socket for lib/select than the current
implementation of VERIFY_SOCK, I'll be glad to study it.

-- 
-=[Yang]=-
Received on 2007-02-01