It took a few beers, but I finally tackled the register-poor i386.  This 
diffs add setjmp cookies and--while we're here--eliminates the use of 
sigblock/sigsetmask.

For bonus points, I scrambled the cookie offsets among the three calls 
(_setjmp/setjmp/sigsetjmp) so if something tries to mix calls, using 
longjmp() on a buffer from sigsetjmp(), for example, it'll find itself at 
a random address.

This is the diff -w output to it easier to see what is actually changing.  
The real diff has more whitespace adjustments to line up columns.

No regressions against regress/lib/libc/*setjmp*

ok?

Philip Guenther


Index: arch/i386/gen/_setjmp.S
===================================================================
RCS file: /data/src/openbsd/src/lib/libc/arch/i386/gen/_setjmp.S,v
retrieving revision 1.5
diff -u -p -w -r1.5 _setjmp.S
--- arch/i386/gen/_setjmp.S     7 Aug 2005 11:30:38 -0000       1.5
+++ arch/i386/gen/_setjmp.S     29 May 2016 08:46:27 -0000
@@ -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)
+       call    1f
+1:     popl    %ecx
+       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     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)
Index: arch/i386/gen/setjmp.S
===================================================================
RCS file: /data/src/openbsd/src/lib/libc/arch/i386/gen/setjmp.S,v
retrieving revision 1.10
diff -u -p -w -r1.10 setjmp.S
--- arch/i386/gen/setjmp.S      13 Sep 2015 07:36:58 -0000      1.10
+++ arch/i386/gen/setjmp.S      29 May 2016 09:10:57 -0000
@@ -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,63 @@
  */
 
 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 */
+       subl    $4,%esp
+       movl    $(SYS_sigprocmask),%eax
+       int     $0x80                   /* leave oset in %eax */
+       addl    $12,%esp
 
-       movl    4(%esp),%ecx
-       movl    0(%esp),%edx
-       movl    %edx, 0(%ecx)
+       call    1f
+1:     popl    %edx
+       addl    __jmpxor-1b,%edx        # load cookie address
+
+       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 */
+       subl    $4,%esp
+       movl    $(SYS_sigprocmask),%eax
+       int     $0x80
+       addl    $12,%esp
+
+       call    1f
+1:     popl    %ecx
+       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     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)
Index: arch/i386/gen/sigsetjmp.S
===================================================================
RCS file: /data/src/openbsd/src/lib/libc/arch/i386/gen/sigsetjmp.S,v
retrieving revision 1.9
diff -u -p -w -r1.9 sigsetjmp.S
--- arch/i386/gen/sigsetjmp.S   13 Sep 2015 07:36:58 -0000      1.9
+++ arch/i386/gen/sigsetjmp.S   29 May 2016 09:11:22 -0000
@@ -31,7 +31,9 @@
  * SUCH DAMAGE.
  */
 
-#include <machine/asm.h>
+#include "SYS.h"
+
+       .global __jmpxor
 
 ENTRY(sigsetjmp)
        movl    4(%esp),%ecx
@@ -40,53 +42,67 @@ 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:     call    2f
+2:     popl    %ecx
+       addl    __jmpxor-2b,%ecx        # load cookie address
 
-1:     movl    4(%esp),%edx
+       movl     4(%esp),%edx
        movl    8(%esp),%eax
-       movl    0(%edx),%ecx
        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    8(%edx),%esp
        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)

Reply via email to