From 7f2e7047951962198ce1315756c9fbd053e6f046 Mon Sep 17 00:00:00 2001 From: david Date: Thu, 10 Apr 2008 01:51:05 +0000 Subject: [PATCH] Reduce the maximum number of sockets from max_sd() - 4 to max_sd() - 5. I've foudn that five files can be open on Mac OS X: stdin, stdout, stderr, /dev/tty, and /private/var/run/utmpx. This could cause a non-root scan at a high scan rateto fail with the message "Too many open files". I was able to cause this with "nmap --min-rate 5000 localhost -p-". That command still fails with the same error message, but for an entirely different reason. After a while, one of the connect calls fails with an errno of 22 = EINVAL, Invalid argument. Whatever this means, the socket doesn't get closed, Nmap just reports a "Strange error from connect". The socket is still open but Nmap doesn't include it in its count of open sockets, so it's off by one (or more, conceivably). This allows it to try to open one too many sockets and bomb with an error message. Note that running as non-root is important both because it uses a connect scan and because non-root users have a lower limit on open files. I've tried just closing the socket when EINVAL is returned, and that fixes the problem. But that's likely to differ on different systems. Plus I don't know why EINVAL is returned; maybe it's an OS bug. This only affects localhost scans and only at high scan rates, so I'm leaving it alone. --- scan_engine.cc | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/scan_engine.cc b/scan_engine.cc index 1410ebf82..9f4d25945 100644 --- a/scan_engine.cc +++ b/scan_engine.cc @@ -821,7 +821,13 @@ void UltraProbe::setConnect(u16 portno) { ConnectScanInfo::ConnectScanInfo() { maxValidSD = -1; numSDs = 0; - maxSocketsAllowed = (o.max_parallelism)? o.max_parallelism : MAX(5, max_sd() - 4); + /* Subtracting 5 from max_sd accounts for + stdin + stdout + stderr + /dev/tty + /var/run/utmpx, which is opened on Mac OS X at least. */ + maxSocketsAllowed = (o.max_parallelism)? o.max_parallelism : MAX(5, max_sd() - 5); FD_ZERO(&fds_read); FD_ZERO(&fds_write); FD_ZERO(&fds_except);