mirror of
https://sourceware.org/git/glibc.git
synced 2024-11-09 23:00:07 +00:00
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:
parent
e646a161ce
commit
98b78b4b72
2
NEWS
2
NEWS
@ -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.
|
||||
|
@ -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]
|
||||
|
@ -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)
|
||||
|
@ -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"
|
||||
|
@ -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)
|
||||
|
13
ports/sysdeps/unix/sysv/linux/ia64/sigaltstack-offsets.sym
Normal file
13
ports/sysdeps/unix/sysv/linux/ia64/sigaltstack-offsets.sym
Normal 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
|
Loading…
Reference in New Issue
Block a user