lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite for Android: free password hash cracker in your pocket
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <Pine.NEB.4.61.0505060156210.19421@speedy.ludd.ltu.se>
Date: Fri May  6 15:01:51 2005
From: jlo at ludd.luth.se (Lars Olsson)
Subject: 64 bit qmail fun

On Fri, 6 May 2005, Georgi Guninski wrote:

> Georgi Guninski security advisory #74, 2005
>
> 64 bit qmail fun
>
> Systems affected:
> qmail on 64 bit platforms with a lot of virtual memory ( ~ >8GB)
>
> Date: 6 May 2005

[snip]


Hehe...darn, you beat me to it...I've been sitting on this for some
time now...

I noticed the problem with the heap-allocation wrapper alloc() in alloc.c 
(also affects djbdns BTW although I haven't found a way to trigger for 
it):

static aligned realspace[SPACE / ALIGNMENT];
#define space ((char *) realspace)
static unsigned int avail = SPACE; /* multiple of ALIGNMENT; 
0<=avail<=SPACE */

/*@...l@...*@out@...har *alloc(n)
unsigned int n;
{
   char *x;
   n = ALIGNMENT + n - (n & (ALIGNMENT - 1)); /* XXX: could overflow */
                                                 ^^^^^^^^^^^^^^^^^^^
   if (n <= avail) { avail -= n; return space + avail; }
   x = malloc(n);
   if (!x) errno = error_nomem;
   return x;
}

Notice the XXX? :)

If n > 0xfffffff0 the alignment adjustment will truncate n to 0
which means the pointer returned will be to the static realspace buffer.
This step does not require a 64-bit architecture!

However, the only way I've found so far to trigger the integer overflow is 
via the stralloc_* routines used in a manner that grows the buffer one 
byte at a time, for instance in qmail-smtpd.c commands() loop (function 
pointer is placed after realspace on my test compilations BTW). 
Hence 64-bit arch with lots of mem is necessary in this case. I don't 
think it's possible to break out of the byte_copy routine though 
unfortunately (or fortunately, depending on which side of the fence 
you're on.)

There are usually checks for excessive lenghts before the other 
alloc-routines that specifies length explicitly (and without copying),
especially in djbdns since DNS packets only are 2^16 bytes max (or some 
such, I forget.)

It might well be that qmail and djbdns are immune to exploits, but it
is a good idea to patch alloc() in alloc.c anyway, for instance like:

if (n >= 0xfffffff0) {
  	errno = error_nomem;
 	return NULL;
}

(Crude and for more general operations should be rewritten to allow larger
allocations, but for qmail and djbns it should be good enough since 
hopefulyl one doesn't need that much memory to run them efficiently...)

Don't have time to write more now...apologize if I screwed something up in 
my extreme hurry...


Cheers,
Lars

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ