From 2342e643d4c998ae314d03d207f703c1cc5159e4 Mon Sep 17 00:00:00 2001 From: Josh Gao Date: Wed, 16 Sep 2015 18:42:45 -0700 Subject: [PATCH] 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 -- 2.11.0