summaryrefslogtreecommitdiff
path: root/lib/libc/arch/i386
diff options
context:
space:
mode:
authorPhilip Guenther <guenther@cvs.openbsd.org>2016-05-30 02:11:22 +0000
committerPhilip Guenther <guenther@cvs.openbsd.org>2016-05-30 02:11:22 +0000
commit60a28108f00ae01ff33c3a8b7476fde5be2c8c58 (patch)
tree7e85317ae633662d843d2232f33f604c14b05a17 /lib/libc/arch/i386
parente70ca08d00eea5b0c152315cf48fcf4adbb139e0 (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.S37
-rw-r--r--lib/libc/arch/i386/gen/setjmp.S80
-rw-r--r--lib/libc/arch/i386/gen/sigsetjmp.S77
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)