Subject: Re: Fork bomb protection patch (Was: Re: CVS commit: syssrc/sys/kern)
To: Jaromir Dolecek <jdolecek@netbsd.org>
From: Roland Dowdeswell <elric@imrryr.org>
List: tech-kern
Date: 12/06/2002 23:58:32
On 1039220330 seconds since the Beginning of the UNIX epoch
Jaromir Dolecek wrote:
>
>Bill Studenmund wrote:
>>

>It's my understanding the time-sharing scheduler doesn't cope with
>the fork-bomb too well, since there is huge number of CPU hungry
>processes. As a result, each gets only fraction of CPU, collects
>CPU ticks very slowly and thus it's priority won't get lowered
>quickly enough. Thus, it's priority pretty much stays at PUSER and
>effectiverly block process activity on this priority.

Well, the time sharing scheduler is going to fairly shedule the
processes.  The reason that the system becomes sluggish is that
you are competing with too many processes and hence get a very
small amount of the system's time.

>> 3) What about Roland's modified bomb? I haven't tried it, but I trust him
>> when he says that, even when he added a 1 second wait after fork failures
>> (to simulate your .5 sec wait), it behaved the same. Thus the delay
>> doesn't stop that bomb; the scope of this fix is limited and easily
>> circumvented.
>
>Andrew already answered this one. Roland's modified bomb used
>for(;;) after fork() failure, not a sleep(1).

I put the sleep(1) in as an approximation of the tsleep change,
but it was not in the code that I posted.  The reason that my
program worked as effectively is that the sluggishness caused by
the fork-bomb is mainly caused by busy-looping processes---it does
not really matter what they're doing, you cause resource starvation
by having too much competition for the CPU.

Andrew and I discussed a few fork-bomb variants offline before I
posted to tech-kern and I believe that he was discussing a prior
version that had not addressed all of his objections.

>Arguably, the sleep doesn't make any difference to behaviour
>perceived by most programs.  Most programs just busy loop trying
>fork() for EAGAIN case, thus effectively 'freeze' when they hit
>limit too.  Other programs exit with error if fork() fails. The
>latter programs would just take a bit longer to return the error,
>which would normally be perceived as system overload (which would
>be right). All in all, it pretty much behaves as before, just spends
>less system resources on it.

I do not buy this, and have presented one example where this is
not the case.  thttpd neither busy loops on fork(), nor exits on
fork() failure.  I am guessing that inetd, sshd, etc. probably fall
into the same boat of neither busy-looping nor exiting.  I'd actually
suggest that the general case is neither of those conditions, but
depends on what the daemon in question is trying to do.  The reason
that I chose thttpd off the top of my head was that it is a program
that performs work in a hybrid event-driven/fork model and hence
it is easy to see that arbitrarily enforced sleeps will cause it
to behave in unexpected fashions.  I am sure that there are other
examples.

--
    Roland Dowdeswell                      http://www.Imrryr.ORG/~elric/