You are viewing a plain text version of this content. The canonical link for it is here.
Posted to apache-bugdb@apache.org by Dean Gaudet <dg...@apache.org> on 1997/08/21 08:20:02 UTC

other/1028: DoS attacks involving memory consumption

>Number:         1028
>Category:       other
>Synopsis:       DoS attacks involving memory consumption
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    apache (Apache HTTP Project)
>State:          open
>Class:          change-request
>Submitter-Id:   apache
>Arrival-Date:   Wed Aug 20 23:20:01 1997
>Originator:     dgaudet@apache.org
>Organization:
apache
>Release:        1.3a2-dev and earlier
>Environment:
all
>Description:
Apache will accept an unlimited number of headers.  The child will consume
arbitrary amounts of memory.  The child does not exit until its max#requests
which means that swap space is consumed for possibly a long time.  If this
is done to all children then it could consume all available swap.

There are several issues here:

We could possibly protect against such "obvious" DoS attacks, but we'll
never catch all of them.  As was demonstrated with qmail recently the single
best solution is OS-enforced resource limits.

Apache might be able to do something more finegrained by tracking memory usage
in pools.  There should still be a global resource limit for a child.  There
could be some advantages to tracking pools... other than limiting the size of
any particular pool.  For example, a child could actually return a server error
rather than taking a SIGBUS and dying mysteriously.

If the parent knew the memory size of its children it could favour killing off
large children.  It would probably have to be stored in the scoreboard.  Doing
a getrusage() on every hit is expensive, once per 10 or 100 hits is probably
enough.  Given pool size tracking a child would know when it had exceeded,
say 40% of its resource limit, and then willingly offer itself up for killing.

We never free() any memory allocated.  This is unfortunate on unixes such as
FreeBSD and Linux, and on NT and OS/2 which all have the ability to return
memory from an application to the global pool.  Maybe there is a good scheme
which can return "extra" blocks at the end of a request -- preferably the
most recently malloc()d blocks because that probably improves fragmentation.
>How-To-Repeat:

>Fix:

>Audit-Trail:
>Unformatted: