mirror of
git://git.musl-libc.org/musl
synced 2024-12-14 18:55:23 +00:00
redesign sigsetjmp so that signal mask is restored after longjmp
the conventional way to implement sigsetjmp is to save the signal mask then tail-call to setjmp; siglongjmp then restores the signal mask and calls longjmp. the problem with this approach is that a signal already pending, or arriving between unmasking of signals and restoration of the saved stack pointer, will have its signal handler run on the stack that was active before siglongjmp was called. this can lead to unbounded stack usage when siglongjmp is used to leave a signal handler. in the new design, sigsetjmp saves its own return address inside the extended part of the sigjmp_buf (outside the __jmp_buf part used by setjmp) then calls setjmp to save a jmp_buf inside its own execution. it then tail-calls to __sigsetjmp_tail, which uses the return value of setjmp to determine whether to save the current signal mask or restore a previously-saved mask. as an added bonus, this design makes it so that siglongjmp and longjmp are identical. this is useful because the __longjmp_chk function we need to add for ABI-compatibility assumes siglongjmp and longjmp are the same, but for different reasons -- it was designed assuming either can access a flag just past the __jmp_buf indicating whether the signal masked was saved, and act on that flag. however, early versions of musl did not have space past the __jmp_buf for the non-sigjmp_buf version of jmp_buf, so our setjmp cannot store such a flag without risking clobbering memory on (very) old binaries.
This commit is contained in:
parent
81e18eb3cd
commit
583e55122e
@ -4,16 +4,18 @@
|
||||
.type __sigsetjmp,%function
|
||||
sigsetjmp:
|
||||
__sigsetjmp:
|
||||
str x1,[x0,#176]
|
||||
cbz x1,setjmp
|
||||
|
||||
// TODO errno?
|
||||
// sigprocmask(SIG_SETMASK, 0, (sigset_t*)buf->__ss);
|
||||
stp x0,x30,[sp,#-16]!
|
||||
add x2,x0,#184
|
||||
mov x1,#0
|
||||
mov x0,#2
|
||||
bl sigprocmask
|
||||
ldp x0,x30,[sp],#16
|
||||
str lr,[x0,#176]
|
||||
str x19,[x0,#176+8+8]
|
||||
mov x19,x0
|
||||
|
||||
b setjmp
|
||||
bl setjmp
|
||||
|
||||
mov w1,w0
|
||||
mov x0,x19
|
||||
ldr lr,[x0,#176]
|
||||
ldr x19,[x0,#176+8+8]
|
||||
|
||||
.hidden __sigsetjmp_tail
|
||||
b __sigsetjmp_tail
|
||||
|
@ -4,13 +4,19 @@
|
||||
.type __sigsetjmp,%function
|
||||
sigsetjmp:
|
||||
__sigsetjmp:
|
||||
str a2,[a1,#256]
|
||||
tst a2,a2
|
||||
tst r1,r1
|
||||
beq setjmp
|
||||
push {a1,lr}
|
||||
add a3,a1,#260
|
||||
mov a2,#0
|
||||
mov a1,#2
|
||||
bl sigprocmask
|
||||
pop {a1,lr}
|
||||
b setjmp
|
||||
|
||||
str lr,[r0,#256]
|
||||
str r4,[r0,#260+8]
|
||||
mov r4,r0
|
||||
|
||||
bl setjmp
|
||||
|
||||
mov r1,r0
|
||||
mov r0,r4
|
||||
ldr lr,[r0,#256]
|
||||
ldr r4,[r0,#260+8]
|
||||
|
||||
.hidden __sigsetjmp_tail
|
||||
b __sigsetjmp_tail
|
||||
|
@ -4,14 +4,22 @@
|
||||
.type __sigsetjmp,@function
|
||||
sigsetjmp:
|
||||
__sigsetjmp:
|
||||
mov 4(%esp),%eax
|
||||
mov 8(%esp),%ecx
|
||||
mov %ecx,24(%eax)
|
||||
jecxz 1f
|
||||
add $28,%eax
|
||||
push %eax
|
||||
push $0
|
||||
push $2
|
||||
call sigprocmask
|
||||
add $12,%esp
|
||||
|
||||
mov 4(%esp),%eax
|
||||
popl 24(%eax)
|
||||
mov %ebx,28+8(%eax)
|
||||
mov %eax,%ebx
|
||||
|
||||
call setjmp
|
||||
|
||||
pushl 24(%ebx)
|
||||
mov %ebx,4(%esp)
|
||||
mov %eax,8(%esp)
|
||||
mov 28+8(%ebx),%ebx
|
||||
|
||||
.hidden __sigsetjmp_tail
|
||||
jmp __sigsetjmp_tail
|
||||
|
||||
1: jmp setjmp
|
||||
|
@ -4,18 +4,18 @@
|
||||
.type __sigsetjmp,@function
|
||||
sigsetjmp:
|
||||
__sigsetjmp:
|
||||
swi r6, r5, 72
|
||||
beqi r6, setjmp@PLT
|
||||
beqi r6, setjmp@PLT
|
||||
|
||||
addi r1, r1, -32
|
||||
swi r15, r1, 28
|
||||
swi r5, r1, 24
|
||||
addi r7, r5, 76
|
||||
add r6, r0, r0
|
||||
brlid r15, sigprocmask@PLT
|
||||
ori r5, r0, 2
|
||||
swi r15,r5,72
|
||||
swi r19,r5,72+4+8
|
||||
|
||||
lwi r15, r1, 28
|
||||
lwi r5, r1, 24
|
||||
brid setjmp@PLT
|
||||
addi r1, r1, 32
|
||||
brlid r15,setjmp@PLT
|
||||
ori r19,r5,0
|
||||
|
||||
ori r6,r3,0
|
||||
ori r5,r19,0
|
||||
lwi r15,r5,72
|
||||
lwi r19,r5,72+4+8
|
||||
|
||||
.hidden __sigsetjmp_tail
|
||||
bri __sigsetjmp_tail
|
||||
|
@ -9,22 +9,25 @@ __sigsetjmp:
|
||||
lui $gp, %hi(_gp_disp)
|
||||
addiu $gp, %lo(_gp_disp)
|
||||
beq $5, $0, 1f
|
||||
addu $gp, $gp, $25
|
||||
subu $sp, $sp, 32
|
||||
sw $4, 20($sp)
|
||||
sw $ra, 24($sp)
|
||||
sw $gp, 28($sp)
|
||||
addu $6, $4, 108
|
||||
li $5, 0
|
||||
li $4, 1
|
||||
sw $4, -4($6)
|
||||
lw $25, %call16(sigprocmask)($gp)
|
||||
addu $gp, $gp, $25
|
||||
|
||||
sw $ra, 104($4)
|
||||
sw $16, 104+4+16($4)
|
||||
|
||||
lw $25, %call16(setjmp)($gp)
|
||||
jalr $25
|
||||
nop
|
||||
lw $gp, 28($sp)
|
||||
lw $ra, 24($sp)
|
||||
lw $4, 20($sp)
|
||||
addu $sp, $sp, 32
|
||||
move $16, $4
|
||||
|
||||
move $5,$2
|
||||
move $4,$16
|
||||
lw $ra, 104($4)
|
||||
lw $16, 104+4+16($4)
|
||||
|
||||
.hidden __sigsetjmp_tail
|
||||
lw $25, %call16(__sigsetjmp_tail)($gp)
|
||||
jr $25
|
||||
nop
|
||||
|
||||
1: lw $25, %call16(setjmp)($gp)
|
||||
jr $25
|
||||
nop
|
||||
nop
|
||||
|
@ -6,17 +6,18 @@ sigsetjmp:
|
||||
__sigsetjmp:
|
||||
l.sfeq r4, r0
|
||||
l.bf plt(setjmp)
|
||||
l.sw 52(r3), r4 /* buf->__fl = save */
|
||||
|
||||
l.addi r1, r1, -8
|
||||
l.sw 0(r1), r9
|
||||
l.sw 4(r1), r3
|
||||
l.addi r5, r3, 56 /* buf->__ss */
|
||||
l.add r4, r0, r0
|
||||
l.jal plt(sigprocmask)
|
||||
l.ori r3, r0, 2 /* SIG_SETMASK */
|
||||
l.sw 52(r3), r9
|
||||
l.sw 52+4+8(r3), r20
|
||||
|
||||
l.lwz r9, 0(r1)
|
||||
l.lwz r3, 4(r1)
|
||||
l.j plt(setjmp)
|
||||
l.addi r1, r1, 8
|
||||
l.jal plt(setjmp)
|
||||
l.ori r20, r3, 0
|
||||
|
||||
l.ori r4, r11, 0
|
||||
l.ori r3, r20, 0
|
||||
|
||||
l.lwz r9, 52(r3)
|
||||
|
||||
.hidden __sigsetjmp_tail
|
||||
l.j plt(__sigsetjmp_tail)
|
||||
l.lwz r20, 52+4+8(r3)
|
||||
|
@ -4,35 +4,23 @@
|
||||
.type __sigsetjmp,%function
|
||||
sigsetjmp:
|
||||
__sigsetjmp:
|
||||
#int sigsetjmp(sigjmp_buf buf, int save)
|
||||
# r3 r4
|
||||
#0) store save into buf->__fl
|
||||
stw 4, 448(3)
|
||||
#1) compare save with 0
|
||||
cmpwi cr7, 4, 0
|
||||
#2) if its 0, goto setjmp code
|
||||
beq- cr7, 1f
|
||||
#3) else: we must call pthread_sigmask(SIG_SETMASK, 0, (sigset_t *)buf->__ss);
|
||||
# store non-volatile regs 30, 31 into the setjmp buf
|
||||
stw 30, 0(3)
|
||||
stw 31, 4(3)
|
||||
# use them to store the pointer to the jmpbuf and the link reg
|
||||
mr 30, 3
|
||||
mflr 31
|
||||
|
||||
# put pointer to ss buf into r5 (3rd arg)
|
||||
addi 5, 3, 452
|
||||
# put "2" i.e. SIG_SETMASK in r3
|
||||
li 3, 2
|
||||
li 4, 0
|
||||
bl pthread_sigmask
|
||||
|
||||
#restore jmpbuf pointer and link reg
|
||||
mr 3, 30
|
||||
mtlr 31
|
||||
#resore non-volatile regs
|
||||
lwz 30, 0(3)
|
||||
lwz 31, 4(3)
|
||||
|
||||
1:
|
||||
b setjmp
|
||||
mflr 5
|
||||
stw 5, 448(3)
|
||||
stw 16, 448+4+8(3)
|
||||
mr 16, 3
|
||||
|
||||
bl setjmp
|
||||
|
||||
mr 4, 3
|
||||
mr 3, 16
|
||||
lwz 5, 448(3)
|
||||
mtlr 5
|
||||
lwz 16, 448+4+8(3)
|
||||
|
||||
.hidden __sigsetjmp_tail
|
||||
b __sigsetjmp_tail
|
||||
|
||||
1: b setjmp
|
||||
|
@ -4,27 +4,37 @@
|
||||
.type __sigsetjmp,@function
|
||||
sigsetjmp:
|
||||
__sigsetjmp:
|
||||
mov.l r5, @(36,r4)
|
||||
tst r5, r5
|
||||
bf 2f
|
||||
bt 9f
|
||||
|
||||
sts.l pr, @-r15
|
||||
mov.l r4, @-r15
|
||||
mov r4, r6
|
||||
add #40, r6
|
||||
mov #0, r5
|
||||
mov #2, r4
|
||||
mov.l L1, r0
|
||||
bsrf r0
|
||||
nop
|
||||
1: mov.l @r15+, r4
|
||||
lds.l @r15+, pr
|
||||
add #52, r6
|
||||
sts pr, r0
|
||||
mov.l r0, @r6
|
||||
mov.l r8, @(4+8,r6)
|
||||
|
||||
2: mov.l L2, r0
|
||||
braf r0
|
||||
mov.l 1f, r0
|
||||
2: bsrf r0
|
||||
mov r4, r8
|
||||
|
||||
mov r0, r5
|
||||
mov r8, r4
|
||||
mov r4, r6
|
||||
add #52, r6
|
||||
|
||||
mov.l @r6, r0
|
||||
lds r0, pr
|
||||
|
||||
mov.l 3f, r0
|
||||
4: braf r0
|
||||
mov.l @(4+8,r4), r8
|
||||
|
||||
9: mov.l 5f, r0
|
||||
6: braf r0
|
||||
nop
|
||||
3:
|
||||
|
||||
.align 2
|
||||
L1: .long pthread_sigmask@PLT-(1b-.)
|
||||
L2: .long setjmp@PLT-(3b-.)
|
||||
1: .long setjmp@PLT-(2b+4-.)
|
||||
.hidden __sigsetjmp_tail
|
||||
3: .long __sigsetjmp_tail@PLT-(4b+4-.)
|
||||
5: .long setjmp@PLT-(6b+4-.)
|
||||
|
@ -5,6 +5,5 @@
|
||||
|
||||
_Noreturn void siglongjmp(sigjmp_buf buf, int ret)
|
||||
{
|
||||
if (buf->__fl) __restore_sigs(buf->__ss);
|
||||
longjmp(buf, ret);
|
||||
}
|
||||
|
13
src/signal/sigsetjmp_tail.c
Normal file
13
src/signal/sigsetjmp_tail.c
Normal file
@ -0,0 +1,13 @@
|
||||
#include <setjmp.h>
|
||||
#include <signal.h>
|
||||
#include "syscall.h"
|
||||
|
||||
#ifdef SHARED
|
||||
__attribute__((__visibility__("hidden")))
|
||||
#endif
|
||||
int __sigsetjmp_tail(sigjmp_buf jb, int ret)
|
||||
{
|
||||
void *p = jb->__ss;
|
||||
__syscall(SYS_rt_sigprocmask, SIG_SETMASK, ret?p:0, ret?0:p, _NSIG/8);
|
||||
return ret;
|
||||
}
|
@ -1,17 +1,24 @@
|
||||
/* Copyright 2011-2012 Nicholas J. Kain, licensed under standard MIT license */
|
||||
.global sigsetjmp
|
||||
.global __sigsetjmp
|
||||
.type sigsetjmp,@function
|
||||
.type __sigsetjmp,@function
|
||||
sigsetjmp:
|
||||
__sigsetjmp:
|
||||
andl %esi,%esi
|
||||
movq %rsi,64(%rdi)
|
||||
test %esi,%esi
|
||||
jz 1f
|
||||
pushq %rdi
|
||||
leaq 72(%rdi),%rdx
|
||||
xorl %esi,%esi
|
||||
movl $2,%edi
|
||||
call sigprocmask
|
||||
popq %rdi
|
||||
|
||||
popq 64(%rdi)
|
||||
mov %rbx,72+8(%rdi)
|
||||
mov %rdi,%rbx
|
||||
|
||||
call setjmp
|
||||
|
||||
pushq 64(%rbx)
|
||||
mov %rbx,%rdi
|
||||
mov %eax,%esi
|
||||
mov 72+8(%rbx),%rbx
|
||||
|
||||
.hidden __sigsetjmp_tail
|
||||
jmp __sigsetjmp_tail
|
||||
|
||||
1: jmp setjmp
|
||||
|
@ -1,17 +1,24 @@
|
||||
/* Copyright 2011-2012 Nicholas J. Kain, licensed under standard MIT license */
|
||||
.global sigsetjmp
|
||||
.global __sigsetjmp
|
||||
.type sigsetjmp,@function
|
||||
.type __sigsetjmp,@function
|
||||
sigsetjmp:
|
||||
__sigsetjmp:
|
||||
andl %esi,%esi
|
||||
movq %rsi,64(%rdi)
|
||||
test %esi,%esi
|
||||
jz 1f
|
||||
pushq %rdi
|
||||
leaq 72(%rdi),%rdx
|
||||
xorl %esi,%esi
|
||||
movl $2,%edi
|
||||
call sigprocmask
|
||||
popq %rdi
|
||||
|
||||
popq 64(%rdi)
|
||||
mov %rbx,72+8(%rdi)
|
||||
mov %rdi,%rbx
|
||||
|
||||
call setjmp
|
||||
|
||||
pushq 64(%rbx)
|
||||
mov %rbx,%rdi
|
||||
mov %eax,%esi
|
||||
mov 72+8(%rbx),%rbx
|
||||
|
||||
.hidden __sigsetjmp_tail
|
||||
jmp __sigsetjmp_tail
|
||||
|
||||
1: jmp setjmp
|
||||
|
Loading…
Reference in New Issue
Block a user