mirror of
git://sourceware.org/git/glibc.git
synced 2024-11-21 01:12:26 +08: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,
|
16038, 16041, 16055, 16071, 16072, 16074, 16077, 16078, 16103, 16112,
|
||||||
16143, 16144, 16146, 16150, 16151, 16153, 16167, 16172, 16195, 16214,
|
16143, 16144, 16146, 16150, 16151, 16153, 16167, 16172, 16195, 16214,
|
||||||
16245, 16271, 16274, 16283, 16289, 16293, 16314, 16316, 16330, 16337,
|
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
|
* Slovenian translations for glibc messages have been contributed by the
|
||||||
Translation Project's Slovenian team of translators.
|
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>
|
2013-12-30 Mike Frysinger <vapier@gentoo.org>
|
||||||
|
|
||||||
[BZ #16379]
|
[BZ #16379]
|
||||||
|
@ -10,6 +10,7 @@ endif
|
|||||||
ifeq ($(subdir),misc)
|
ifeq ($(subdir),misc)
|
||||||
sysdep_headers += sys/io.h
|
sysdep_headers += sys/io.h
|
||||||
sysdep_routines += ioperm clone2
|
sysdep_routines += ioperm clone2
|
||||||
|
gen-as-const-headers += sigaltstack-offsets.sym
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(subdir),elf)
|
ifeq ($(subdir),elf)
|
||||||
|
@ -15,6 +15,8 @@
|
|||||||
License along with the GNU C Library; if not, see
|
License along with the GNU C Library; if not, see
|
||||||
<http://www.gnu.org/licenses/>. */
|
<http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
#include <sigaltstack-offsets.h>
|
||||||
|
|
||||||
.section .rodata.str1.8,"aMS",@progbits,1
|
.section .rodata.str1.8,"aMS",@progbits,1
|
||||||
.align 8
|
.align 8
|
||||||
.LC0:
|
.LC0:
|
||||||
@ -29,13 +31,58 @@ longjmp_msg:
|
|||||||
|
|
||||||
#define __longjmp ____longjmp_chk
|
#define __longjmp ____longjmp_chk
|
||||||
|
|
||||||
#define CHECK_RSP(reg) \
|
/* We use 32 bytes (rather than sizeof(stack_t)) so that we keep the stack
|
||||||
cmp.ltu p0, p8 = reg, r12; \
|
properly aligned. But we still want a sanity check to make sure 32 is
|
||||||
(p8) br.cond.dpnt .Lok;; \
|
actually enough. */
|
||||||
addl r28 = @ltoffx(longjmp_msg#), r1;; \
|
#define STACK_SPACE ((sizeSS + 31) & -32)
|
||||||
ld8.mov r28 = [r28], longjmp_msg#;; \
|
|
||||||
ld8 out0 = [r28]; \
|
/* 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)#;; \
|
br.call.sptk.many b0 = HIDDEN_JUMPTARGET(__fortify_fail)#;; \
|
||||||
.Lok:
|
.Lok: \
|
||||||
|
add r12 = STACK_SPACE, r12;
|
||||||
|
|
||||||
#include "__longjmp.S"
|
#include "__longjmp.S"
|
||||||
|
@ -42,9 +42,10 @@
|
|||||||
|
|
||||||
LEAF(__longjmp)
|
LEAF(__longjmp)
|
||||||
#ifdef CHECK_RSP
|
#ifdef CHECK_RSP
|
||||||
alloc r8=ar.pfs,2,1,1,0
|
alloc r8=ar.pfs,2,1,3,0
|
||||||
|
CHECK_RSP
|
||||||
#else
|
#else
|
||||||
alloc r8=ar.pfs,2,1,0,0
|
alloc r8=ar.pfs,2,0,0,0
|
||||||
#endif
|
#endif
|
||||||
mov r27=ar.rsc
|
mov r27=ar.rsc
|
||||||
add r2=0x98,in0 // r2 <- &jmpbuf.orig_jmp_buf_addr
|
add r2=0x98,in0 // r2 <- &jmpbuf.orig_jmp_buf_addr
|
||||||
@ -79,9 +80,6 @@ LEAF(__longjmp)
|
|||||||
mov r26=ar.rnat
|
mov r26=ar.rnat
|
||||||
mov ar.unat=r25 // setup ar.unat (NaT bits for r1, r4-r7, and r12)
|
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)
|
ld8.fill.nta gp=[r3],32 // r1 (gp)
|
||||||
dep r11=-1,r23,3,6 // r11 <- ia64_rse_rnat_addr(jmpbuf.ar_bsp)
|
dep r11=-1,r23,3,6 // r11 <- ia64_rse_rnat_addr(jmpbuf.ar_bsp)
|
||||||
mov sp=r28 // r12 (sp)
|
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