diff options
author | Josh Gao <jmgao@google.com> | 2016-03-29 14:03:09 -0700 |
---|---|---|
committer | Josh Gao <jmgao@google.com> | 2016-03-29 18:07:32 -0700 |
commit | 7af64bd083a86df3ec2322892a5fcfcc075c2114 (patch) | |
tree | 7b81e459b106ac03ac1e5465da72a6eae7d61600 /libc | |
parent | 9ce09e423f24823d52f19ab8247e078977100132 (diff) | |
download | android_bionic-7af64bd083a86df3ec2322892a5fcfcc075c2114.tar.gz android_bionic-7af64bd083a86df3ec2322892a5fcfcc075c2114.tar.bz2 android_bionic-7af64bd083a86df3ec2322892a5fcfcc075c2114.zip |
Add a checksum to jmp_buf on x86.
Bug: http://b/27856501
Bug: http://b/27417786
Change-Id: Id5a0a81fc38e311bff678cbc7dc2219bc0074503
(cherry picked from commit 926078539346f5d3cc864c9ba25993e8c6437c07)
Diffstat (limited to 'libc')
-rw-r--r-- | libc/arch-x86/bionic/setjmp.S | 39 |
1 files changed, 38 insertions, 1 deletions
diff --git a/libc/arch-x86/bionic/setjmp.S b/libc/arch-x86/bionic/setjmp.S index 86e6e3cd5..efb645993 100644 --- a/libc/arch-x86/bionic/setjmp.S +++ b/libc/arch-x86/bionic/setjmp.S @@ -32,6 +32,21 @@ #include <private/bionic_asm.h> +// The internal structure of a jmp_buf is totally private. +// Current layout (changes from release to release): +// +// word name description +// 0 edx registers +// 1 ebx +// 2 esp +// 3 ebp +// 4 esi +// 5 edi +// 6 sigmask signal mask (not used with _setjmp / _longjmp) +// 7 sigflag/cookie setjmp cookie in top 31 bits, signal mask flag in low bit +// 8 checksum checksum of the core registers, to give better error messages. +// 9 reserved + #define _JB_EDX 0 #define _JB_EBX 1 #define _JB_ESP 2 @@ -40,6 +55,7 @@ #define _JB_EDI 5 #define _JB_SIGMASK 6 #define _JB_SIGFLAG 7 +#define _JB_CHECKSUM 8 .macro m_mangle_registers reg xorl \reg,%edx @@ -54,6 +70,13 @@ m_mangle_registers \reg .endm +.macro m_calculate_checksum dst, src + movl $0, \dst + .irp i,0,1,2,3,4,5 + xorl (\i*4)(\src), \dst + .endr +.endm + ENTRY(setjmp) movl 4(%esp),%ecx mov $1,%eax @@ -111,13 +134,22 @@ ENTRY(sigsetjmp) movl %edi,(_JB_EDI * 4)(%ecx) m_unmangle_registers %eax + m_calculate_checksum %eax, %ecx + movl %eax, (_JB_CHECKSUM * 4)(%ecx) + xorl %eax,%eax ret END(sigsetjmp) ENTRY(siglongjmp) - // Do we have a signal mask to restore? movl 4(%esp),%edx + + // Check the checksum before doing anything. + m_calculate_checksum %eax, %edx + xorl (_JB_CHECKSUM * 4)(%edx), %eax + jnz 3f + + // Do we have a signal mask to restore? movl (_JB_SIGFLAG * 4)(%edx), %eax testl $1,%eax jz 1f @@ -165,6 +197,11 @@ ENTRY(siglongjmp) 2: movl %ecx,0(%esp) ret + +3: + PIC_PROLOGUE + pushl (_JB_SIGMASK * 4)(%edx) + call PIC_PLT(__bionic_setjmp_checksum_mismatch) END(siglongjmp) ALIAS_SYMBOL(longjmp, siglongjmp) |