This adds xor cookies to the arm setjmp family.

To make the register jockeying easier, it rearranges the order of the 
registers in the jmpbuf, moving up the (cookied) sp and lr registers to 
before r4-r11, and then completely leaving out r12, as it's not 
callee-saved in the ABI.  Thus the first file in the diff here, 
<arm/setjmp.h>, showing the new layout.

This is an ABI break for anything that pokes into jmpbuf; does it need to 
ride on a libc major bump?


Philip


Index: sys/arch/arm/include/setjmp.h
===================================================================
RCS file: /cvs/src/sys/arch/arm/include/setjmp.h,v
retrieving revision 1.3
diff -u -p -w -r1.3 setjmp.h
--- sys/arch/arm/include/setjmp.h       9 Feb 2013 20:52:12 -0000       1.3
+++ sys/arch/arm/include/setjmp.h       6 Aug 2016 19:22:09 -0000
@@ -8,11 +8,6 @@
 #define        _JBLEN  64              /* size, in longs, of a jmp_buf */
 
 /*
- * NOTE: The internal structure of a jmp_buf is *PRIVATE*
- *       This information is provided as there is software
- *       that fiddles with this with obtain the stack pointer
- *      (yes really ! and it's commercial !).
- *
  * Description of the setjmp buffer
  *
  * word  0     magic number    (dependant on creator)
@@ -21,17 +16,17 @@
  *      7 -  9 f6              fp register 6
  *     10 - 12 f7              fp register 7
  *     13      fpsr            fp status register
- *     14      r4              register 4
- *     15      r5              register 5
- *     16      r6              register 6
- *     17      r7              register 7
- *     18      r8              register 8
- *     19      r9              register 9
- *     20      r10             register 10 (sl)
- *     21      r11             register 11 (fp)
- *     22      r12             register 12 (ip)
- *     23      r13             register 13 (sp)
- *     24      r14             register 14 (lr)
+ *     14      r13             register 13 (sp) XOR cookie0
+ *     15      r14             register 14 (lr) XOR cookie1
+ *     16      r4              register 4
+ *     17      r5              register 5
+ *     18      r6              register 6
+ *     19      r7              register 7
+ *     20      r8              register 8
+ *     21      r9              register 9
+ *     22      r10             register 10 (sl)
+ *     23      r11             register 11 (fp)
+ *     24      unused          unused
  *     25      signal mask     (dependant on magic)
  *     26      (con't)
  *     27      (con't)
@@ -66,17 +61,14 @@
 #define _JB_REG_F6              7
 #define _JB_REG_F7             10
 #define _JB_REG_FPSR           13
-#define _JB_REG_R4             14
-#define _JB_REG_R5             15
-#define _JB_REG_R6             16
-#define _JB_REG_R7             17
-#define _JB_REG_R8             18
-#define _JB_REG_R9             19
-#define _JB_REG_R10            20
-#define _JB_REG_R11            21
-#define _JB_REG_R12            22
-#define _JB_REG_R13            23
-#define _JB_REG_R14            24
+#define _JB_REG_R4             16
+#define _JB_REG_R5             17
+#define _JB_REG_R6             18
+#define _JB_REG_R7             19
+#define _JB_REG_R8             20
+#define _JB_REG_R9             21
+#define _JB_REG_R10            22
+#define _JB_REG_R11            23
 
 /* Only valid with the _JB_MAGIC_SETJMP magic */
 
Index: lib/libc/arch/arm/gen/_setjmp.S
===================================================================
RCS file: /cvs/src/lib/libc/arch/arm/gen/_setjmp.S,v
retrieving revision 1.4
diff -u -p -w -r1.4 _setjmp.S
--- lib/libc/arch/arm/gen/_setjmp.S     6 Aug 2016 19:16:09 -0000       1.4
+++ lib/libc/arch/arm/gen/_setjmp.S     6 Aug 2016 19:22:09 -0000
@@ -36,6 +36,15 @@
 #include "DEFS.h"
 #include <machine/setjmp.h>
 
+       .section        .openbsd.randomdata,"aw",%progbits
+       .align 4
+       .globl  __jmpxor
+__jmpxor:
+       .zero 4*2               /* (sp, lr) */
+       END(__jmpxor)
+       .type   __jmpxor,%object
+
+
 /*
  * C library -- _setjmp, _longjmp
  *
@@ -52,6 +61,13 @@
 ENTRY(_setjmp)
        ldr     r1, .L_setjmp_magic
        str     r1, [r0], #4
+       ldr     r2, .L_jmpxor_setjmp
+1:     add     r2, pc, r2                      /* r2 = &__jmpxor */
+       ldr     r3, [r2], #4                    /* r3 = __jmpxor[1] */
+       ldr     r2, [r2]                        /* r2 = __jmpxor[0] */
+       eor     r2, r13, r2                     /* r2 = sp ^ __jmpxor[0] */
+       eor     r3, lr, r3                      /* r3 = lr ^ __jmpxor[1] */
+
 #ifdef SOFTFLOAT
        add     r0, r0, #52
 #else
@@ -62,13 +78,17 @@ ENTRY(_setjmp)
        str     r1, [r0], #0x0004
 #endif /* SOFTFLOAT */
        /* Store integer registers */
-        stmia  r0, {r4-r14}
+       stmia   r0, {r2-r11}
 
         mov    r0, #0x00000000
-        mov    r15, r14
+       mov     r2, r0                          /* overwrite __jmpxor copies */
+       mov     r3, r0
+       mov     pc, lr
 
 .L_setjmp_magic:
        .word   _JB_MAGIC__SETJMP
+.L_jmpxor_setjmp:
+       .word   __jmpxor - 1b
 END_STRONG(_setjmp)
 
 ENTRY(_longjmp)
@@ -87,18 +107,30 @@ ENTRY(_longjmp)
        wfs     r4
 #endif /* SOFTFLOAT */
                /* Restore integer registers */
-        ldmia  r0, {r4-r14}
+       ldmia   r0, {r2-r11}
 
-       /* Validate sp and r14 */
+       ldr     r0, .L_jmpxor_longjmp
+1:     add     r0, pc, r0                      /* r0 = &__jmpxor */
+       ldr     lr, [r0], #4                    /* lr = __jmpxor[1] */
+       eor     lr, r3, lr                      /* lr ^= jmpbuf[LR] */
+       ldr     r0, [r0]                        /* r0 = __jmpxor[0] */
+       eor     r13, r0, r2             /* sp = __jmpxor[0] ^ jmpbuf[SP] */
+       mov     r2, r1                          /* overwrite __jmpxor copies */
+       mov     r3, r1
+
+       /* Validate sp and lr */
        teq     sp, #0
-       teqne   r14, #0
+       teqne   lr, #0
        beq     botch
 
        /* Set return value */
        mov     r0, r1
        teq     r0, #0x00000000
        moveq   r0, #0x00000001
-       mov     r15, r14
+       mov     pc, lr
+
+.L_jmpxor_longjmp:
+       .word   __jmpxor - 1b
 
        /* validation failed, die die die. */
 botch:
Index: lib/libc/arch/arm/gen/setjmp.S
===================================================================
RCS file: /cvs/src/lib/libc/arch/arm/gen/setjmp.S,v
retrieving revision 1.5
diff -u -p -w -r1.5 setjmp.S
--- lib/libc/arch/arm/gen/setjmp.S      6 Aug 2016 19:16:09 -0000       1.5
+++ lib/libc/arch/arm/gen/setjmp.S      6 Aug 2016 19:22:09 -0000
@@ -33,9 +33,11 @@
  * SUCH DAMAGE.
  */
 
-#include "DEFS.h"
+#include "SYS.h"
 #include <machine/setjmp.h>
 
+       .hidden __jmpxor
+
 /*
  * C library -- setjmp, longjmp
  *
@@ -48,36 +50,45 @@
 
 ENTRY(setjmp)
        /* Block all signals and retrieve the old signal mask */
-       stmfd   sp!, {r0, r14}
-       mov     r0, #0x00000000
-
-       bl      _HIDDEN(sigblock)
-       mov     r1, r0
-
-       ldmfd   sp!, {r0, r14}
+       mov     r2, r0
+       mov     r1, #0x00000000
+       mov     r0, #0x00000001                 /* SIG_BLOCK */
+       SYSTRAP(sigprocmask)
 
        /* Store signal mask */
-       str     r1, [r0, #(25 * 4)]
+       str     r0, [r2, #(25 * 4)]
 
        ldr     r1, .Lsetjmp_magic
-       str     r1, [r0], #4
+       str     r1, [r2], #4
+
+       ldr     r12, .L_jmpxor_setjmp
+1:     add     r12, pc, r12                    /* r12 = &__jmpxor */
+       ldr     r3, [r12], #4                   /* r3 = __jmpxor[1] */
+       ldr     r12, [r12]                      /* r12 = __jmpxor[0] */
+       eor     r12, r13, r12                   /* r12 = sp ^ __jmpxor[0] */
+       eor     r3, lr, r3                      /* r3 = lr ^ __jmpxor[1] */
 
 #ifdef SOFTFLOAT
-       add     r0, r0, #52
+       add     r2, r2, #52
 #else
        /* Store fp registers */
-       sfm     f4, 4, [r0], #48
+       sfm     f4, 4, [r2], #48
        /* Store fpsr */
        rfs     r1
-       str     r1, [r0], #0x0004
+       str     r1, [r2], #0x0004
 #endif /*SOFTFLOAT*/
        /* Store integer registers */
-        stmia  r0, {r4-r14}
+       stmia   r2, {r3-r12}
+
         mov    r0, #0x00000000
-        mov    r15, r14
+       mov     r12, r0                         /* overwrite __jmpxor copies */
+       mov     r3, r0
+       mov     pc, lr
 
 .Lsetjmp_magic:
        .word   _JB_MAGIC_SETJMP
+.L_jmpxor_setjmp:
+       .word   __jmpxor - 1b
 END_STRONG(setjmp)
 
 
@@ -87,47 +98,48 @@ ENTRY(longjmp)
        teq     r2, r3
        bne     botch
 
-       /* Fetch signal mask */
-       ldr     r2, [r0, #(25 * 4)]
-
-       /* Set signal mask */
-       stmfd   sp!, {r0, r1, r14}
-       sub     sp, sp, #4      /* align the stack */
+       /* Fetch signal mask and call sigprocmask */
+       mov     r3, r0                          /* r3 = jmpbuf */
+       mov     r2, r1                          /* r2 = retvalue */
+       ldr     r1, [r0, #(25 * 4)]
+       mov     r0, #0x00000003                 /* SIG_SETMASK */
+       SYSTRAP(sigprocmask)
 
-       mov     r0, r2
-       bl      _HIDDEN(sigsetmask)
-
-       add     sp, sp, #4      /* unalign the stack */
-       ldmfd   sp!, {r0, r1, r14} 
-
-       add     r0, r0, #4
+       add     r3, r3, #4
 #ifdef SOFTFLOAT
-       add     r0, r0, #52
+       add     r3, r3, #52
 #else
        /* Restore fp registers */
-       lfm     f4, 4, [r0], #48
+       lfm     f4, 4, [r3], #48
        /* Restore FPSR */
-       ldr     r4, [r0], #0x0004
+       ldr     r4, [r3], #0x0004
        wfs     r4
 #endif /* SOFTFLOAT */
        /* Restore integer registers */
-        ldmia  r0, {r4-r14}
+       ldmia   r3, {r3-r12}
+
+       ldr     r0, .L_jmpxor_longjmp
+1:     add     r0, pc, r0              /* r0 = &__jmpxor */
+       ldr     lr, [r0], #4            /* lr = __jmpxor[1] */
+       eor     lr, r3, lr              /* lr ^= jmpbuf[LR] */
+       ldr     r0, [r0]                /* r0 = __jmpxor[0] */
+       eor     r13, r0, r12            /* sp = __jmpxor[0] ^ jmpbuf[SP] */
+       mov     r12, r2                 /* overwrite __jmpxor copies */
+       mov     r3, r2
 
-       /* Validate sp and r14 */
+       /* Validate sp and lr */
        teq     sp, #0
-       teqne   r14, #0
+       teqne   lr, #0
        beq     botch
 
        /* Set return value */
-
-       mov     r0, r1
+       mov     r0, r12
        teq     r0, #0x00000000
        moveq   r0, #0x00000001
-#ifdef __ARM_26__
-       mov     r15, r14
-#else
-       mov     r15, r14
-#endif
+       mov     pc, lr
+
+.L_jmpxor_longjmp:
+       .word   __jmpxor - 1b
 
        /* validation failed, die die die. */
 botch:

Reply via email to