diff options
author | Philip Guenther <guenther@cvs.openbsd.org> | 2016-05-30 02:11:22 +0000 |
---|---|---|
committer | Philip Guenther <guenther@cvs.openbsd.org> | 2016-05-30 02:11:22 +0000 |
commit | 60a28108f00ae01ff33c3a8b7476fde5be2c8c58 (patch) | |
tree | 7e85317ae633662d843d2232f33f604c14b05a17 /lib/libc/arch/i386 | |
parent | e70ca08d00eea5b0c152315cf48fcf4adbb139e0 (diff) |
Do setjmp cookies for eip, esp, and ebp. For bonus points, mix how
the cookies are used in setjmp/_setjmp/sigsetjmp so that mixing
calls (e.g., longjmp on a _setjmp buffer) will scramble all three
registers and jump you to a random location on a random stack!
ok deraadt@
Diffstat (limited to 'lib/libc/arch/i386')
-rw-r--r-- | lib/libc/arch/i386/gen/_setjmp.S | 37 | ||||
-rw-r--r-- | lib/libc/arch/i386/gen/setjmp.S | 80 | ||||
-rw-r--r-- | lib/libc/arch/i386/gen/sigsetjmp.S | 77 |
3 files changed, 124 insertions, 70 deletions
diff --git a/lib/libc/arch/i386/gen/_setjmp.S b/lib/libc/arch/i386/gen/_setjmp.S index ac62635fd26..438689d6d22 100644 --- a/lib/libc/arch/i386/gen/_setjmp.S +++ b/lib/libc/arch/i386/gen/_setjmp.S @@ -1,4 +1,4 @@ -/* $OpenBSD: _setjmp.S,v 1.5 2005/08/07 11:30:38 espie Exp $ */ +/* $OpenBSD: _setjmp.S,v 1.6 2016/05/30 02:11:21 guenther Exp $ */ /*- * Copyright (c) 1990 The Regents of the University of California. * All rights reserved. @@ -33,6 +33,8 @@ #include <machine/asm.h> + .global __jmpxor + /* * C library -- _setjmp, _longjmp * @@ -44,28 +46,45 @@ */ ENTRY(_setjmp) + call 1f +1: popl %ecx + addl $__jmpxor-1b,%ecx # load cookie address movl 4(%esp),%eax movl 0(%esp),%edx - movl %edx, 0(%eax) /* rta */ + xorl 0(%ecx),%edx # use eip cookie + movl %edx, 0(%eax) movl %ebx, 4(%eax) - movl %esp, 8(%eax) - movl %ebp,12(%eax) + movl %esp, %edx + xorl 4(%ecx),%edx # use esp cookie + movl %edx, 8(%eax) + movl 8(%ecx),%ecx # load ebp cookie over cookie address + xorl %ebp, %ecx + movl %ecx,12(%eax) movl %esi,16(%eax) movl %edi,20(%eax) xorl %eax,%eax ret +END(_setjmp) ENTRY(_longjmp) - movl 4(%esp),%edx - movl 8(%esp),%eax - movl 0(%edx),%ecx - movl 4(%edx),%ebx - movl 8(%edx),%esp + call 1f +1: popl %ecx + addl $__jmpxor-1b,%ecx # load cookie address + movl 4(%esp),%edx + movl 8(%esp),%eax + movl 4(%edx),%ebx + movl 8(%edx),%esi # load xor'ed esp into safe register + xorl 4(%ecx),%esi # use esp cookie + movl %esi, %esp # un-xor'ed esp is safe to use movl 12(%edx),%ebp + xorl 8(%ecx),%ebp # use ebp cookie movl 16(%edx),%esi movl 20(%edx),%edi + movl 0(%ecx),%ecx # load eip cookie over cookie address + xorl 0(%edx),%ecx # overwrite eip cookie testl %eax,%eax jnz 1f incl %eax 1: movl %ecx,0(%esp) ret +END(_longjmp) diff --git a/lib/libc/arch/i386/gen/setjmp.S b/lib/libc/arch/i386/gen/setjmp.S index 4f183b2658c..eaeb8737640 100644 --- a/lib/libc/arch/i386/gen/setjmp.S +++ b/lib/libc/arch/i386/gen/setjmp.S @@ -1,4 +1,4 @@ -/* $OpenBSD: setjmp.S,v 1.10 2015/09/13 07:36:58 guenther Exp $ */ +/* $OpenBSD: setjmp.S,v 1.11 2016/05/30 02:11:21 guenther Exp $ */ /*- * Copyright (c) 1990 The Regents of the University of California. * All rights reserved. @@ -31,7 +31,17 @@ * SUCH DAMAGE. */ -#include <machine/asm.h> +#include "SYS.h" + + .section .openbsd.randomdata,"aw",@progbits + .balign 4 + .globl __jmpxor + .hidden __jmpxor +__jmpxor: + .zero 4*3 # (eip, esp, ebp) + END(__jmpxor) + .type __jmpxor,@object + /* * C library -- setjmp, longjmp @@ -44,50 +54,60 @@ */ ENTRY(setjmp) - PIC_PROLOGUE - pushl $0 -#ifdef __PIC__ - call PIC_PLT(_C_LABEL(_libc_sigblock)) -#else - call _C_LABEL(_libc_sigblock) -#endif - addl $4,%esp - PIC_EPILOGUE + pushl $0 /* mask = empty */ + pushl $1 /* how = SIG_BLOCK */ + call 1f +1: movl $(SYS_sigprocmask),%eax + int $0x80 /* leave oset in %eax */ + popl %edx + addl $8,%esp + addl $__jmpxor-1b,%edx # load cookie address movl 4(%esp),%ecx - movl 0(%esp),%edx - movl %edx, 0(%ecx) + movl %eax,24(%ecx) movl %ebx, 4(%ecx) - movl %esp, 8(%ecx) - movl %ebp,12(%ecx) + movl %esp, %eax + xorl 0(%edx),%eax # use esp cookie + movl %eax, 8(%ecx) + movl %ebp, %eax + xorl 4(%edx),%eax # use ebp cookie + movl %eax,12(%ecx) movl %esi,16(%ecx) movl %edi,20(%ecx) - movl %eax,24(%ecx) + movl 8(%edx),%edx # load eip cookie over cookie address + xorl 0(%esp),%edx + movl %edx, 0(%ecx) xorl %eax,%eax ret +END(setjmp) ENTRY(longjmp) movl 4(%esp),%edx - PIC_PROLOGUE - pushl 24(%edx) -#ifdef __PIC__ - call PIC_PLT(_C_LABEL(_libc_sigsetmask)) -#else - call _C_LABEL(_libc_sigsetmask) -#endif - addl $4,%esp - PIC_EPILOGUE + pushl 24(%edx) /* mask from sc_mask */ + pushl $3 /* how = SIG_SETMASK */ + call 1f /* get our eip */ +1: movl $(SYS_sigprocmask),%eax + int $0x80 + popl %ecx + addl $8,%esp + addl $__jmpxor-1b,%ecx # load cookie address - movl 4(%esp),%edx - movl 8(%esp),%eax - movl 0(%edx),%ecx - movl 4(%edx),%ebx - movl 8(%edx),%esp + movl 4(%esp),%edx + movl 8(%esp),%eax + movl 4(%edx),%ebx + movl 8(%edx),%esi # load xor'ed esp into safe register + xorl 0(%ecx),%esi # use esp cookie + movl %esi, %esp # un-xor'ed esp is safe to use movl 12(%edx),%ebp + xorl 4(%ecx),%ebp # use ebp cookie movl 16(%edx),%esi movl 20(%edx),%edi + + movl 8(%ecx),%ecx # load eip cookie over cookie address + xorl 0(%edx),%ecx testl %eax,%eax jnz 1f incl %eax 1: movl %ecx,0(%esp) ret +END(longjmp) diff --git a/lib/libc/arch/i386/gen/sigsetjmp.S b/lib/libc/arch/i386/gen/sigsetjmp.S index 43a7e2b6a35..e27b7accf9a 100644 --- a/lib/libc/arch/i386/gen/sigsetjmp.S +++ b/lib/libc/arch/i386/gen/sigsetjmp.S @@ -1,4 +1,4 @@ -/* $OpenBSD: sigsetjmp.S,v 1.9 2015/09/13 07:36:58 guenther Exp $ */ +/* $OpenBSD: sigsetjmp.S,v 1.10 2016/05/30 02:11:21 guenther Exp $ */ /*- * Copyright (c) 1990 The Regents of the University of California. * All rights reserved. @@ -31,7 +31,9 @@ * SUCH DAMAGE. */ -#include <machine/asm.h> +#include "SYS.h" + + .global __jmpxor ENTRY(sigsetjmp) movl 4(%esp),%ecx @@ -40,53 +42,66 @@ ENTRY(sigsetjmp) testl %eax,%eax jz 1f - PIC_PROLOGUE - pushl $0 -#ifdef __PIC__ - call PIC_PLT(_C_LABEL(_libc_sigblock)) -#else - call _C_LABEL(_libc_sigblock) -#endif - addl $4,%esp - PIC_EPILOGUE - - movl 4(%esp),%ecx + pushl $0 /* mask = empty */ + pushl $1 /* how = SIG_BLOCK */ + subl $4,%esp + movl $(SYS_sigprocmask),%eax + int $0x80 /* leave oset in %eax */ + addl $12,%esp movl %eax,24(%ecx) -1: movl 0(%esp),%edx - movl %edx, 0(%ecx) + +1: call 2f +2: popl %edx + addl $__jmpxor-2b,%edx # load cookie address + movl %ebx, 4(%ecx) - movl %esp, 8(%ecx) - movl %ebp,12(%ecx) + movl %esp, %eax + xorl 8(%edx),%eax # use esp cookie + movl %eax, 8(%ecx) + movl %ebp, %eax + xorl 0(%edx),%eax # use ebp cookie + movl %eax,12(%ecx) movl %esi,16(%ecx) movl %edi,20(%ecx) + movl 4(%edx),%edx # load eip cookie over cookie address + xorl 0(%esp),%edx + movl %edx, 0(%ecx) xorl %eax,%eax ret +END(sigsetjmp) ENTRY(siglongjmp) movl 4(%esp),%edx cmpl $0,28(%edx) jz 1f - PIC_PROLOGUE - pushl 24(%edx) -#ifdef __PIC__ - call PIC_PLT(_C_LABEL(_libc_sigsetmask)) -#else - call _C_LABEL(_libc_sigsetmask) -#endif - addl $4,%esp - PIC_EPILOGUE + pushl 24(%edx) /* mask from sc_mask */ + pushl $3 /* how = SIG_SETMASK */ + subl $4,%esp + movl $(SYS_sigprocmask),%eax + int $0x80 + addl $12,%esp -1: movl 4(%esp),%edx - movl 8(%esp),%eax - movl 0(%edx),%ecx - movl 4(%edx),%ebx - movl 8(%edx),%esp +1: call 2f +2: popl %ecx + addl $__jmpxor-2b,%ecx # load cookie address + + movl 4(%esp),%edx # reload in case sigprocmask failed + movl 8(%esp),%eax + movl 4(%edx),%ebx + movl 8(%edx),%esi # load xor'ed esp into safe register + xorl 8(%ecx),%esi # use esp cookie + movl %esi, %esp # un-xor'ed esp is safe to use movl 12(%edx),%ebp + xorl 0(%ecx),%ebp # use ebp cookie movl 16(%edx),%esi movl 20(%edx),%edi + + movl 4(%ecx),%ecx # load eip cookie over cookie address + xorl 0(%edx),%ecx testl %eax,%eax jnz 2f incl %eax 2: movl %ecx,0(%esp) ret +END(siglongjmp) |