Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 1 Feb 2007 05:06:15 +1100 (EST)
From:      Bruce Evans <bde@zeta.org.au>
To:        "Dr. Markus Waldeck" <waldeck@gmx.de>
Cc:        freebsd-bugs@freebsd.org, freebsd-gnats-submit@freebsd.org
Subject:   Re: bin/108547: top allows local denial of service attack
Message-ID:  <20070201033547.S1153@besplex.bde.org>
In-Reply-To: <200701301125.l0UBPGQZ044694@www.freebsd.org>
References:  <200701301125.l0UBPGQZ044694@www.freebsd.org>

next in thread | previous in thread | raw e-mail | index | archive | help
On Tue, 30 Jan 2007, Dr. Markus Waldeck wrote:

>> Description:
> An unprivileged user could waste all CPU time by setting a low delay value in top (interactive or via -s).

An unprivileged user can waste all CPU time using almost any program.  This
might matter for set[ug]id ones, but top isn't set*id under FreeBSD.

> Is there any possibility to deactivate this functionality without recompilation?

I would have thought that the possibility of making this mistake was
too small for it to happen, but the mistake of not allowing a delay
of 0 has already been made.  Neither restriction is needed.  The
latter restriction is close to being not even wrong, since it is easy
to work around using "while :; do top; done | cat".  (This differs
from top -s 0 mainly in not printing the "CPU states" line.  It also
has formatting bugs, so the null filter (cat) isn't quite enough to
give the same display as top -s 0.)  To actually be wrong, top would
have to ensure that it runs for at least its minumum interval, so that
top in a loop is rate limited.  Non-interactive top for non-DOS purposes
would then be broken.  Fortunately, top can't ensure this, since it
can be SIGKILLed.  All it can do is subtract more value by not displaying
anything until after it has run for its minimum interval (instead of
displaying something and then sleeping), so that anyone who SIGKILLs
it gets nothing.

> There are other top implementations that use a "secure mode" configuration
> which avoids the setting of the delay value for unprivileged users.

Maybe they are worried about it being set*id.  I think most set*id programs
don't actually handle this.  E.g., ping(8) doesn't -- "ping -c1" in a loop
works around ping's limits on -f and its interval.  This actually matters,
since ping can be used for remote DOS.  Fix: ensure that ping runs for at
least its minimum interval.  I think most setuid programs with resource
limits need to do something like:

     privilege checking
     setuid() to drop the user's real ids (until here, can be SIGKILLed by user)
     use resource
     delay for an interval before exiting or using resource again

ping does most of this already.

Bruce



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