lkml.org 
[lkml]   [1998]   [Aug]   [21]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
/
Date
From
SubjectUlimit Probrems with Linux
Hello all,

[Note: This is not a re-submission of the Apache dos Sioux error but a new
problem which is related to it and the patch which was posted.]

Recently on bugtraq there was an Apache dos attack posted that caused an
exponential increase in memory usage by sending multiple headers. The
headers would be merged by sending the string:

User-Agent: [string length of 5]

Sending this 10,000 times would produce the string:

User-Agent [memory consumed=350M]

The problem appears to be in Apache's ap_pstrcat function. The function
concatenates the string by first allocating a new buffer and copies the
data into it. The problem lies in the fact that the function fails to
release the original buffer(s). All of the intermediate states remain in
memory after they should have been released.

The fix that was posted effectively limited the number of headers to 100 by
patching the function that reads them in to memory. This is incomplete
since limiting the number of headers does not limit the size of the header
and therefore does not limit the ultimate size of the string. While the
patch would correct the example previously cited, it would do nothing for
the following:

User-Agent: [string length of 8192]

Sending this 100 times would produce the string:

User-Agent: [memory consumed=42M]

The second example has consumed significantly less memory, however, it is
still far more than should have been. There is also the issue that it
would require very few simultaneous attacks to achieve the same results as
in the first example.

In an attempt to correct the problem altogether ulimit was invoked to
restrict the maximum size of it's data segment instead of trying to hack
Apache's source. Using the shell script command [ulimit -d 2048] prevented
the 40M buffers that were previously occurring, however, instead of taking
up 2M the process took up 10M. This was not the expected result.

Next was to hack Apache to make sure it was not resetting the limits
internally and it did report the correct limit. After adding to the kernel
in /usr/src/linux/mm/mmap.c where it checks the memory limit the kernel
reported that the processes were ok.

Now it is necessary to run some test code to see just what was happening
with the memory allocation. The following is the first test which was run:

#include<stdio.h>
#include<sys/resource.h>

main(int argc,char **argv)
{
unsigned long int total,size;
char *p;

size=65536;
total=0;
for(;;)
{
getchar();
if (!(p=malloc(size)))
{
perror("malloc failed");
for(;;)
;
}

memset(p,0,size);

{
struct rlimit rlim;
getrlimit(RLIMIT_DATA,&rlim);

total=total+size;
fprintf(stderr,"BMA: rlim: %d\n",rlim.rlim_cur);
fprintf(stderr,"BMA: rlim: %lu %lu\n",total,size);
}
}
}

The result here was that just allocating 64k buffers the ulimit invocation
works just fine. The next test is where the problem lies. Using the
following:

#include<stdio.h>
#include<sys/resource.h>

main(int argc,char **argv)
{
unsigned long int total,size;
char *p;

size=65536;
total=0;
for(;;)
{
getchar();
if (!(p=malloc(size)))
{
perror("malloc failed");
for(;;)
;
}

memset(p,0,size);

{
struct rlimit rlim;
getrlimit(RLIMIT_DATA,&rlim);

total=total+size;
fprintf(stderr,"BMA: rlim: %d\n",rlim.rlim_cur);
fprintf(stderr,"BMA: rlim: %lu %lu\n",total,size);
size=size+65536;
}
}
}

results in allocating the increasingly larger blocks which indicates the
ulimit invocation has failed. This represents the same results as the
originally reported Apache dos attack.

From these tests I can only conclude that if you use malloc to allocate
buffers larger than 128k the problem will occur consistently. Even if
ulimit is set to 100 bytes an 8M segment is allocated somewhere. Generally
speaking, most code does not do this, however, this appears to be a case
where Apache does. Either there is a significant flaw in my thinking on
this or a flaw in the way linux is allocating memory. If it's the former,
well, apologies in advance. If it is the latter, I believe it must be
addressed since it creates a vulnerability that represents a serious bug.

The tests were run on both libc5.3.12 and glibc2.0.5 using a linux 2.0.35
kernel. I ran strace on the Apache sever and noticed that it was running
the brk system call to increase the data segment. It was also running
mmap. Is that where the memory is going? I assume that malloc is making
these calls because Apache did not have any mmaps that were in the segment
of code that I was testing.

I wasn't sure whether this would be more appropriate if posted to bugtraq,
linux-kernel or linux- admin so I picked two out of the three.

Thanks,
Brian Ackerman
Computer Resource Center Inc.

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.altern.org/andrebalsa/doc/lkml-faq.html

\
 
 \ /
  Last update: 2005-03-22 13:44    [W:0.354 / U:0.224 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site