On Sun, 29 May 2016, Philip Guenther wrote:
> On Sun, 29 May 2016, Philip Guenther wrote:
> > 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?
> 
> This diff has switched to failing after updating other parts of my src 
> tree, so hold on playing with it for now...

I think I flubbed my test setup before and was 'testing' the unchanged 
libc.  This time the regress tests are happy even after installing the 
updated version and it's successfully done a build and rebooted to it.


Philip

Index: _setjmp.S
===================================================================
RCS file: /data/src/openbsd/src/lib/libc/arch/i386/gen/_setjmp.S,v
retrieving revision 1.5
diff -u -p -r1.5 _setjmp.S
--- _setjmp.S   7 Aug 2005 11:30:38 -0000       1.5
+++ _setjmp.S   29 May 2016 20:12:47 -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)
-       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)
Index: setjmp.S
===================================================================
RCS file: /data/src/openbsd/src/lib/libc/arch/i386/gen/setjmp.S,v
retrieving revision 1.10
diff -u -p -r1.10 setjmp.S
--- setjmp.S    13 Sep 2015 07:36:58 -0000      1.10
+++ setjmp.S    29 May 2016 20:13:39 -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,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)
Index: sigsetjmp.S
===================================================================
RCS file: /data/src/openbsd/src/lib/libc/arch/i386/gen/sigsetjmp.S,v
retrieving revision 1.9
diff -u -p -r1.9 sigsetjmp.S
--- sigsetjmp.S 13 Sep 2015 07:36:58 -0000      1.9
+++ sigsetjmp.S 29 May 2016 20:22:36 -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,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
-
-1:     movl    4(%esp),%edx
-       movl    8(%esp),%eax
-       movl    0(%edx),%ecx
-       movl    4(%edx),%ebx
-       movl    8(%edx),%esp
+       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
+
+       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)

Reply via email to