Date: Sat, 12 Apr 1997 13:03:07 -0300 From: Solar Designer <solar@SUN1.IDEAL.RU> To: BUGTRAQ@netspace.org Subject: Linux kernel patch to remove stack exec permission Message-ID: <199704121603.NAA21137@sun1.ideal.ru>
next in thread | raw e-mail | index | archive | help
Hello! There seemed to be no patch for Linux kernel to remove execute permission from the stack (to prevent most buffer overflow exploits), so I decided to make one, I include it at the end of this message. I heard some rumours that GCC assumes stack frame to be executable when dealing with nested functions, but I couldn't reproduce that. I'm running this patched kernel for a day now, and everything (well, except for the exploits) seems to work fine. However, some programs may depend on the stack being executable... I'd like to hear any reports of this. The patch is for Linux 2.0.30 (should work on others also), x86 only. Originally user code, data and stack segments were mapped to the same memory, and had the same limit. I decreased the code segment's limit, so it doesn't cover the actual stack space (since the stack grows down). Actually, I created a new descriptor instead, leaving the old one with its original limit, since that still allows to execute some code on the stack when needed, by using old code segment selector. For example, the kernel itself needs that ability to return from signal handlers. Note that the BSS and malloc()ed areas are still executable. Some buffer overflows are still exploitable, by making the program put the shellcode somewhere else in its memory space, not on the stack, and overwriting the return address to point to that area. Also, some programs may already have a suitable code in them, and not require an external shellcode at all. So this patch only prevents most overflows from being exploitable, not all of them. diff -u --recursive /extra/linux-2.0.30/arch/i386/kernel/head.S linux/arch/i386/kernel/head.S --- /extra/linux-2.0.30/arch/i386/kernel/head.S Sat Apr 12 10:41:59 1997 +++ linux/arch/i386/kernel/head.S Sat Apr 12 10:44:58 1997 @@ -402,7 +402,7 @@ .quad 0xc0c392000000ffff /* 0x18 kernel 1GB data at 0xC0000000 */ .quad 0x00cbfa000000ffff /* 0x23 user 3GB code at 0x00000000 */ .quad 0x00cbf2000000ffff /* 0x2b user 3GB data at 0x00000000 */ - .quad 0x0000000000000000 /* not used */ + .quad 0x00cafa000000ffff /* 0x33 user 2.75GB code */ .quad 0x0000000000000000 /* not used */ .fill 2*NR_TASKS,8,0 /* space for LDT's and TSS's etc */ #ifdef CONFIG_APM diff -u --recursive /extra/linux-2.0.30/arch/i386/kernel/signal.c linux/arch/i386/kernel/signal.c --- /extra/linux-2.0.30/arch/i386/kernel/signal.c Sat Apr 12 10:41:59 1997 +++ linux/arch/i386/kernel/signal.c Sat Apr 12 10:44:58 1997 @@ -214,7 +214,7 @@ /* Set up registers for signal handler */ regs->esp = (unsigned long) frame; regs->eip = (unsigned long) sa->sa_handler; - regs->cs = USER_CS; regs->ss = USER_DS; + regs->cs = USER_HUGE_CS; regs->ss = USER_DS; regs->ds = USER_DS; regs->es = USER_DS; regs->gs = USER_DS; regs->fs = USER_DS; regs->eflags &= ~TF_MASK; diff -u --recursive /extra/linux-2.0.30/include/asm-i386/segment.h linux/include/asm-i386/segment.h --- /extra/linux-2.0.30/include/asm-i386/segment.h Sat Apr 12 10:41:37 1997 +++ linux/include/asm-i386/segment.h Sat Apr 12 10:44:58 1997 @@ -4,7 +4,8 @@ #define KERNEL_CS 0x10 #define KERNEL_DS 0x18 -#define USER_CS 0x23 +#define USER_HUGE_CS 0x23 +#define USER_CS 0x33 #define USER_DS 0x2B #ifndef __ASSEMBLY__ Signed, Solar Designer
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199704121603.NAA21137>