Firewall Wizards mailing list archives

Linux patch (was: Re: Here is my plan for firewall implementation)


From: Arjan Vos <arjan () pino demon nl>
Date: Wed, 24 Sep 1997 20:57:59 +0200 (MET DST)

Paul,

Below I included Solar Designers improved version of the Linux patch you
refered to.

Gr. Arjan

--
Eat hard
Sleep hard
Wear glasses if you need them

---------- Forwarded message ----------
Date: Sun, 13 Apr 1997 16:06:38 -0300
From: Solar Designer <solar () SUN1 IDEAL RU>
To: BUGTRAQ () netspace org
Subject: 2nd Linux kernel patch to remove stack exec

[...snip...]

To enable/disable execution permission on the stack in your programs (who
would need that, with such a GPF handler?), the following can be used:

#include <asm/segment.h>
[...]
/* Switch to huge code segment => executable stack */
        asm("ljmp %0,$1f\n1:\n" : : "i" (USER_HUGE_CS));
/* Switch to truncated code segment => non-executable stack */
        asm("ljmp %0,$1f\n1:\n" : : "i" (USER_CS));

If someone really uses these, it might be reasonable to make such macros in
asm/segment.h, so the stuff looks more readable.

And now the patch... (to make it work with 2.1.x, change "cs" to "xcs" for
signal.c and traps.c).

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/arch/i386/kernel/traps.c linux/arch/i386/kernel/traps.c
--- /extra/linux-2.0.30/arch/i386/kernel/traps.c        Sat Apr 12 10:41:59 1997
+++ linux/arch/i386/kernel/traps.c      Sun Apr 13 07:22:44 1997
@@ -198,6 +198,14 @@
                return;
        }
        die_if_kernel("general protection",regs,error_code);
+       if (regs->cs == USER_CS && get_seg_byte(USER_DS, (char *)regs->eip) != 0xC3) {
+/*
+ * Switch to the original huge code segment (and allow code execution on the
+ * stack for this entire process), unless the faulty instruction is a RET.
+ */
+               regs->cs = USER_HUGE_CS;
+               return;
+       }
        current->tss.error_code = error_code;
        current->tss.trap_no = 13;
        force_sig(SIGSEGV, current);
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__

[...snip...]





Current thread: