ia64: longjmp_chk: support signal stacks [BZ #16372]

The sp check has to be moved up to the start of the func since it now
makes a system call and that'll clobber a lot of registers.

URL: https://sourceware.org/bugzilla/show_bug.cgi?id=16372
Signed-off-by: Mike Frysinger <vapier@gentoo.org>
This commit is contained in:
Mike Frysinger 2013-12-29 21:16:25 +00:00
parent e646a161ce
commit 98b78b4b72
6 changed files with 83 additions and 13 deletions

2
NEWS
View File

@ -23,7 +23,7 @@ Version 2.19
16038, 16041, 16055, 16071, 16072, 16074, 16077, 16078, 16103, 16112,
16143, 16144, 16146, 16150, 16151, 16153, 16167, 16172, 16195, 16214,
16245, 16271, 16274, 16283, 16289, 16293, 16314, 16316, 16330, 16337,
16338, 16356, 16369, 16375.
16338, 16356, 16369, 16372, 16375.
* Slovenian translations for glibc messages have been contributed by the
Translation Project's Slovenian team of translators.

View File

@ -1,3 +1,14 @@
2013-12-30 Mike Frysinger <vapier@gentoo.org>
* sysdeps/unix/sysv/linux/ia64/Makefile (gen-as-const-headers): Add
sigaltstack-offsets.sym.
* sysdeps/unix/sysv/linux/ia64/____longjmp_chk.S: Include new
sigaltstack-offsets.h header.
(STACK_SPACE): Define.
(CHECK_RSP): Rewrite to support sigaltstack.
* sysdeps/unix/sysv/linux/ia64/__longjmp.S: Move CHECK_RSP to top.
* sysdeps/unix/sysv/linux/ia64/sigaltstack-offsets.sym: New file.
2013-12-30 Mike Frysinger <vapier@gentoo.org>
[BZ #16379]

View File

@ -10,6 +10,7 @@ endif
ifeq ($(subdir),misc)
sysdep_headers += sys/io.h
sysdep_routines += ioperm clone2
gen-as-const-headers += sigaltstack-offsets.sym
endif
ifeq ($(subdir),elf)

View File

@ -15,6 +15,8 @@
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
#include <sigaltstack-offsets.h>
.section .rodata.str1.8,"aMS",@progbits,1
.align 8
.LC0:
@ -29,13 +31,58 @@ longjmp_msg:
#define __longjmp ____longjmp_chk
#define CHECK_RSP(reg) \
cmp.ltu p0, p8 = reg, r12; \
(p8) br.cond.dpnt .Lok;; \
addl r28 = @ltoffx(longjmp_msg#), r1;; \
ld8.mov r28 = [r28], longjmp_msg#;; \
ld8 out0 = [r28]; \
/* We use 32 bytes (rather than sizeof(stack_t)) so that we keep the stack
properly aligned. But we still want a sanity check to make sure 32 is
actually enough. */
#define STACK_SPACE ((sizeSS + 31) & -32)
/* Check the stack pointer held in the jumpbuf. Make sure it's in either the
current stack (r12) or in the signal stack. */
#define CHECK_RSP \
ld8 loc0 = [in0]; \
;; \
/* First see if target stack is within current one. */ \
cmp.ltu p0, p8 = loc0, r12; \
(p8) br.cond.dptk.many .Lok; \
\
/* Check if it's an alternative signal stack. */ \
mov out0 = r0; \
add out1 = -STACK_SPACE, r12; \
;; \
mov r12 = out1; \
DO_CALL_VIA_BREAK (SYS_ify (sigaltstack)); \
;; \
/* If the syscall failed, then assume it's OK. */ \
cmp.eq p8, p0 = -1, r10; \
(p8) br.cond.spnt .Lok; \
/* Move stack_t into regs. */ \
add r14 = oSS_FLAGS, r12; /* ss_flags */ \
add r15 = oSS_SIZE, r12; /* ss_size */ \
ld8 r16 = [r12]; /* ss_sp */ \
;; \
ld4 r17 = [r14]; /* ss_flags */ \
ld8 r18 = [r15]; /* ss_size */ \
;; \
sub r19 = r16, r18; /* sp - size */ \
/* See if we're currently on the altstack. */ \
tbit.nz p0, p8 = r17, 0; /* SS_ONSTACK */ \
(p8) br.cond.spnt .Lfail; \
/* Verify target is within alternative stack. */ \
cmp.gtu p7, p0 = loc0, r16; \
(p7) br.cond.spnt .Lfail; \
;; \
cmp.ltu p0, p8 = loc0, r19; \
(p8) br.cond.sptk.many .Lok; \
;; \
\
/* Still here? Abort! */ \
.Lfail: \
add r12 = STACK_SPACE, r12; \
addl loc0 = @ltoffx(longjmp_msg#), r1;; \
ld8.mov loc0 = [loc0], longjmp_msg#;; \
ld8 out0 = [loc0]; \
br.call.sptk.many b0 = HIDDEN_JUMPTARGET(__fortify_fail)#;; \
.Lok:
.Lok: \
add r12 = STACK_SPACE, r12;
#include "__longjmp.S"

View File

@ -42,9 +42,10 @@
LEAF(__longjmp)
#ifdef CHECK_RSP
alloc r8=ar.pfs,2,1,1,0
alloc r8=ar.pfs,2,1,3,0
CHECK_RSP
#else
alloc r8=ar.pfs,2,1,0,0
alloc r8=ar.pfs,2,0,0,0
#endif
mov r27=ar.rsc
add r2=0x98,in0 // r2 <- &jmpbuf.orig_jmp_buf_addr
@ -79,9 +80,6 @@ LEAF(__longjmp)
mov r26=ar.rnat
mov ar.unat=r25 // setup ar.unat (NaT bits for r1, r4-r7, and r12)
;;
#ifdef CHECK_RSP
CHECK_RSP (r28)
#endif
ld8.fill.nta gp=[r3],32 // r1 (gp)
dep r11=-1,r23,3,6 // r11 <- ia64_rse_rnat_addr(jmpbuf.ar_bsp)
mov sp=r28 // r12 (sp)

View File

@ -0,0 +1,13 @@
#include <stddef.h>
#include <signal.h>
--
#define sigaltstack(member) offsetof (stack_t, member)
sizeSS sizeof (stack_t)
oSS_SP sigaltstack (ss_sp)
oSS_FLAGS sigaltstack (ss_flags)
oSS_SIZE sigaltstack (ss_size)
SS_ONSTACK