From 85c14fb086e92b2c774ce8d8f6e4cde8d8a745b7 Mon Sep 17 00:00:00 2001 From: Josh Gao Date: Tue, 15 Sep 2015 11:30:35 -0700 Subject: [PATCH 1/2] Implement setjmp cookies on x86. Bug: http://b/23942752 Change-Id: I2014f95989d0ab094b225234d98ccee477166c9d --- libc/arch-x86/bionic/setjmp.S | 72 +++++++++++++++++++++++++++-------- 1 file changed, 57 insertions(+), 15 deletions(-) diff --git a/libc/arch-x86/bionic/setjmp.S b/libc/arch-x86/bionic/setjmp.S index 18ad810ee..8a2f30cc3 100644 --- a/libc/arch-x86/bionic/setjmp.S +++ b/libc/arch-x86/bionic/setjmp.S @@ -41,30 +41,49 @@ #define _JB_SIGMASK 6 #define _JB_SIGFLAG 7 +.macro m_mangle_registers reg + xorl \reg,%edx + xorl \reg,%ebx + xorl \reg,%esp + xorl \reg,%ebp + xorl \reg,%esi + xorl \reg,%edi +.endm + +.macro m_unmangle_registers reg + m_mangle_registers \reg +.endm + ENTRY(setjmp) movl 4(%esp),%ecx - movl $1,(_JB_SIGFLAG * 4)(%ecx) - jmp .L_sigsetjmp_signal_mask + mov $1,%eax + jmp .L_sigsetjmp END(setjmp) ENTRY(_setjmp) movl 4(%esp),%ecx - movl $0,(_JB_SIGFLAG * 4)(%ecx) - jmp .L_sigsetjmp_no_signal_mask + movl $0,%eax + jmp .L_sigsetjmp END(_setjmp) ENTRY(sigsetjmp) movl 4(%esp),%ecx movl 8(%esp),%eax - // Record whether or not the signal mask is valid. +.L_sigsetjmp: + PIC_PROLOGUE + pushl %eax + call PIC_PLT(__bionic_setjmp_cookie_get) + addl $4,%esp + PIC_EPILOGUE + + // Record the setjmp cookie and whether or not we're saving the signal mask. movl %eax,(_JB_SIGFLAG * 4)(%ecx) // Do we need to save the signal mask? - testl %eax,%eax + testl $1,%eax jz 1f -.L_sigsetjmp_signal_mask: // Get the current signal mask. PIC_PROLOGUE pushl $0 @@ -76,16 +95,21 @@ ENTRY(sigsetjmp) movl 4(%esp),%ecx movl %eax,(_JB_SIGMASK * 4)(%ecx) -.L_sigsetjmp_no_signal_mask: 1: + // Fetch the setjmp cookie and clear the signal flag bit. + movl (_JB_SIGFLAG * 4)(%ecx),%eax + andl $-2,%eax + // Save the callee-save registers. movl 0(%esp),%edx + m_mangle_registers %eax movl %edx,(_JB_EDX * 4)(%ecx) movl %ebx,(_JB_EBX * 4)(%ecx) movl %esp,(_JB_ESP * 4)(%ecx) movl %ebp,(_JB_EBP * 4)(%ecx) movl %esi,(_JB_ESI * 4)(%ecx) movl %edi,(_JB_EDI * 4)(%ecx) + m_unmangle_registers %eax xorl %eax,%eax ret @@ -94,7 +118,8 @@ END(sigsetjmp) ENTRY(siglongjmp) // Do we have a signal mask to restore? movl 4(%esp),%edx - cmpl $0,(_JB_SIGFLAG * 4)(%edx) + movl (_JB_SIGFLAG * 4)(%edx), %eax + testl $1,%eax jz 1f // Restore the signal mask. @@ -108,12 +133,29 @@ ENTRY(siglongjmp) // Restore the callee-save registers. movl 4(%esp),%edx movl 8(%esp),%eax - movl (_JB_EDX * 4)(%edx),%ecx - movl (_JB_EBX * 4)(%edx),%ebx - movl (_JB_ESP * 4)(%edx),%esp - movl (_JB_EBP * 4)(%edx),%ebp - movl (_JB_ESI * 4)(%edx),%esi - movl (_JB_EDI * 4)(%edx),%edi + + movl (_JB_SIGFLAG * 4)(%edx),%ecx + andl $-2,%ecx + + movl %ecx,%ebx + movl %ecx,%esp + movl %ecx,%ebp + movl %ecx,%esi + movl %ecx,%edi + xorl (_JB_EDX * 4)(%edx),%ecx + xorl (_JB_EBX * 4)(%edx),%ebx + xorl (_JB_ESP * 4)(%edx),%esp + xorl (_JB_EBP * 4)(%edx),%ebp + xorl (_JB_ESI * 4)(%edx),%esi + xorl (_JB_EDI * 4)(%edx),%edi + + PIC_PROLOGUE + pushl %eax + pushl (_JB_SIGFLAG * 4)(%edx) + call PIC_PLT(__bionic_setjmp_cookie_check) + addl $4,%esp + popl %eax + PIC_EPILOGUE testl %eax,%eax jnz 2f From 2342e643d4c998ae314d03d207f703c1cc5159e4 Mon Sep 17 00:00:00 2001 From: Josh Gao Date: Wed, 16 Sep 2015 18:42:45 -0700 Subject: [PATCH 2/2] Implement setjmp cookies on x86_64. Bug: http://b/23942752 Change-Id: Iea8d03de1dd9ca5a128c072c94b10de3a8056348 --- libc/arch-x86_64/bionic/setjmp.S | 51 +++++++++++++++++++++++++++++--- 1 file changed, 47 insertions(+), 4 deletions(-) diff --git a/libc/arch-x86_64/bionic/setjmp.S b/libc/arch-x86_64/bionic/setjmp.S index 5559f54c3..09d61f5d9 100644 --- a/libc/arch-x86_64/bionic/setjmp.S +++ b/libc/arch-x86_64/bionic/setjmp.S @@ -50,6 +50,25 @@ #define _JB_SIGMASK 9 #define _JB_SIGMASK_RT 10 // sigprocmask will write here too. +#define MANGLE_REGISTERS 1 +.macro m_mangle_registers reg +#if MANGLE_REGISTERS + xorq \reg,%rbx + xorq \reg,%rbp + xorq \reg,%r12 + xorq \reg,%r13 + xorq \reg,%r14 + xorq \reg,%r15 + xorq \reg,%rsp + xorq \reg,%r11 +#endif +.endm + +.macro m_unmangle_registers reg + m_mangle_registers \reg +.endm + + ENTRY(setjmp) movl $1,%esi jmp PIC_PLT(sigsetjmp) @@ -62,11 +81,17 @@ END(_setjmp) // int sigsetjmp(sigjmp_buf env, int save_signal_mask); ENTRY(sigsetjmp) - // Record whether or not we're saving the signal mask. - movl %esi,(_JB_SIGFLAG * 8)(%rdi) + pushq %rdi + movq %rsi,%rdi + call PIC_PLT(__bionic_setjmp_cookie_get) + popq %rdi + + // Record setjmp cookie and whether or not we're saving the signal mask. + movq %rax,(_JB_SIGFLAG * 8)(%rdi) + pushq %rax // Do we need to save the signal mask? - testl %esi,%esi + testq $1,%rax jz 2f // Save current signal mask. @@ -79,7 +104,10 @@ ENTRY(sigsetjmp) 2: // Save the callee-save registers. + popq %rax + andq $-2,%rax movq (%rsp),%r11 + m_mangle_registers %rax movq %rbx,(_JB_RBX * 8)(%rdi) movq %rbp,(_JB_RBP * 8)(%rdi) movq %r12,(_JB_R12 * 8)(%rdi) @@ -88,6 +116,7 @@ ENTRY(sigsetjmp) movq %r15,(_JB_R15 * 8)(%rdi) movq %rsp,(_JB_RSP * 8)(%rdi) movq %r11,(_JB_PC * 8)(%rdi) + m_unmangle_registers %rax xorl %eax,%eax ret @@ -99,7 +128,9 @@ ENTRY(siglongjmp) pushq %rsi // Push 'value'. // Do we need to restore the signal mask? - cmpl $0,(_JB_SIGFLAG * 8)(%rdi) + movq (_JB_SIGFLAG * 8)(%rdi), %rdi + pushq %rdi // Push cookie + testq $1, %rdi jz 2f // Restore the signal mask. @@ -109,6 +140,10 @@ ENTRY(siglongjmp) call PIC_PLT(sigprocmask) 2: + // Fetch the setjmp cookie and clear the signal flag bit. + popq %rcx + andq $-2, %rcx + popq %rax // Pop 'value'. // Restore the callee-save registers. @@ -120,7 +155,15 @@ ENTRY(siglongjmp) movq (_JB_RSP * 8)(%r12),%rsp movq (_JB_PC * 8)(%r12),%r11 movq (_JB_R12 * 8)(%r12),%r12 + m_unmangle_registers %rcx + // Check the cookie. + pushq %rax + movq %rcx, %rdi + call PIC_PLT(__bionic_setjmp_cookie_check) + popq %rax + + // Return 1 if value is 0. testl %eax,%eax jnz 1f incl %eax