Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 27 Aug 1997 12:56:26 +0930 (CST)
From:      newton@communica.com.au (Mark Newton)
To:        Shimon@i-Connect.Net (Simon Shapiro)
Cc:        freebsd-security@FreeBSD.ORG
Subject:   Re: FW: Denial-of-service attack against INETD.  Redhat 4.X and othe
Message-ID:  <9708270326.AA12076@communica.com.au>
In-Reply-To: <XFMail.970826185921.Shimon@i-Connect.Net> from "Simon Shapiro" at Aug 26, 97 06:59:21 pm

next in thread | previous in thread | raw e-mail | index | archive | help
Simon Shapiro wrote:

 > Have you guys seen, or care about that?

Richard Hipp continues:

    [ snipt ... too many service invocations in a 60 second period ... ]
 > I have implemented changes to the inetd program that address this
 > problem, as follows:  The program still limits the number of services
 > that will be launched within a 60 second window, but it does so by
 > refusing to "accept()" new connections too rapidly.  The listening
 > socket is never closed, and users never get a "Connection refused"
 > error.  They just see a slower response.  For the default value of
 > 40 services/second, inetd will now wait 1500 milliseconds after
 > doing an accept() before doing another accept() on that same service.

Blurgh.  Pity the poor sysadmin who runs httpd out of inetd.

Anyway, this doesn't fix the problem: it makes it worse.  The connection
queue on the accept()ing socket will still impose a limitation on the 
maximum number of outstanding (i.e.: un-accept()ed) connections.  If
the rate of connection attempts exceeds 1 per 1.5 seconds then that
outstanding connection queue will grow up to the maximum length given
in the previous listen() call.  Once that hard limit has been reached,
subsequent connection attempts will fail with ECONNREFUSED, exactly
the same as the error the poster was attempting to avoid.

What kind of weenie posts a long rambling message to CERT about a denial
of service issue that's documented for all to see in the manpage anyway?

 > All services are handled independently, so an accept() for "ftp" will 
 > not impede a subsequence accept() calls on "telnet", for example.
 > Furthermore, the throttling mechanism can be completely disabled by 
 > setting the "max" parameter to "0" in /etc/inetd.conf.

That'd be step one for me if these changes were ever committed :-)

 > In the course of making this change, I discovered and fixed another 
 > small problem with inetd.  It used to be that inetd would sleep
 > (ignoring all connection attempts) for one second after receiving
 > any signal.  This effectivelly limited the number of services that
 > inetd can launch to less than 1 per second, since inetd gets a
 > SIGCHLD signal for every service launched.

Eh?  inetd sleeps in two places:  One of them is when a fork() fails.
The other is when the select() that's used to detect incoming connections
fails (i.e.: returns <= 0).  What has Linux done to their inetd? :-)

 > One other change: it used to be that if bind() fields when setting
 > up a socket, inetd would wait 10 minutes before trying again.  I
 > lowered this value to 10 seconds.

If bind() fails it usually indicates the kind of savage resource shortage
that perfectly justifies backing off for ten minutes or so.  To reduce
this back-off to ten seconds introduces the possibility that inetd
can actually contribute to Denial Of Service problems by compounding
existing resource shortages.

[ as was mentioned in alt.sysadmin.recovery recently:  Has
  anyone ever noticed that there are two common expansions for the
  acronym "DOS", and they both mean the same thing? ]

     - mark

---
Mark Newton                               Email: newton@communica.com.au
Systems Engineer and Senior Trainer       Phone: +61-8-8303-3300
Communica Systems, a member of the        Fax:   +61-8-8303-4403
CAMTECH group of companies                WWW:   http://www.communica.com.au



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?9708270326.AA12076>