musl: Add unwinding protection in clone() implementations.

Whatever was in the frame pointer register prior to clone() will no longer be
valid in the child process, so zero it to protect FP-based unwinders. This is
just an extension of what was already done for i386 and x86_64. Only applied
to architectures where the _start() code also zeroes the frame pointer.
This commit is contained in:
Alex Rønne Petersen 2024-11-13 09:18:37 +01:00
parent da018f9726
commit c666ebb1f8
No known key found for this signature in database
13 changed files with 40 additions and 35 deletions

View File

@ -24,7 +24,8 @@ __clone:
// parent
ret
// child
1: ldp x1,x0,[sp],#16
1: mov fp, 0
ldp x1,x0,[sp],#16
blr x1
mov x8,#93 // SYS_exit
svc #0

View File

@ -19,7 +19,8 @@ __clone:
ldmfd sp!,{r4,r5,r6,r7}
bx lr
1: mov r0,r6
1: mov fp,#0
mov r0,r6
bl 3f
2: mov r7,#1
svc 0

View File

@ -30,9 +30,15 @@ __clone:
mov 8(%ebp),%ebp
int $128
test %eax,%eax
jnz 1f
jz 1f
add $16,%esp
pop %edi
pop %esi
pop %ebx
pop %ebp
ret
mov %ebp,%eax
1: mov %ebp,%eax
xor %ebp,%ebp
call *%eax
mov %eax,%ebx
@ -40,10 +46,3 @@ __clone:
inc %eax
int $128
hlt
1: add $16,%esp
pop %edi
pop %esi
pop %ebx
pop %ebp
ret

View File

@ -22,6 +22,7 @@ __clone:
beqz $a0, 1f # whether child process
jirl $zero, $ra, 0 # parent process return
1:
move $fp, $zero
ld.d $t8, $sp, 0 # function pointer
ld.d $a0, $sp, 8 # argument pointer
jirl $ra, $t8, 0 # call the user's function

View File

@ -18,7 +18,8 @@ __clone:
beq 1f
movem.l (%sp)+,%d2-%d5
rts
1: move.l %a1,-(%sp)
1: suba.l %%fp,%%fp
move.l %a1,-(%sp)
jsr (%a0)
move.l #1,%d0
trap #0

View File

@ -22,7 +22,8 @@ __clone:
rtsd r15, 8
nop
1: lwi r3, r1, 0
1: add r19, r0, r0
lwi r3, r1, 0
lwi r5, r1, 4
brald r15, r3
nop

View File

@ -27,7 +27,8 @@ __clone:
addu $sp, $sp, 16
jr $ra
nop
1: lw $25, 0($sp)
1: move $fp, $0
lw $25, 0($sp)
lw $4, 4($sp)
jalr $25
nop

View File

@ -25,7 +25,8 @@ __clone:
nop
jr $ra
nop
1: ld $25, 0($sp) # function pointer
1: move $fp, $0
ld $25, 0($sp) # function pointer
ld $4, 8($sp) # argument pointer
jalr $25 # call the user's function
nop

View File

@ -25,7 +25,8 @@ __clone:
nop
jr $ra
nop
1: lw $25, 0($sp) # function pointer
1: move $fp, $0
lw $25, 0($sp) # function pointer
lw $4, 4($sp) # argument pointer
jalr $25 # call the user's function
nop

View File

@ -23,7 +23,8 @@ __clone:
l.jr r9
l.nop
1: l.lwz r11, 0(r1)
1: l.ori r2, r0, 0
l.lwz r11, 0(r1)
l.jalr r11
l.lwz r3, 4(r1)

View File

@ -48,9 +48,16 @@ neg 3, 3 #negate the result (errno)
# compare sc result with 0
cmpwi cr7, 3, 0
# if not 0, jump to end
bne cr7, 2f
# if not 0, restore stack and return
beq cr7, 2f
lwz 30, 0(1)
lwz 31, 4(1)
addi 1, 1, 16
blr
2:
#else: we're the child
#call funcptr: move arg (d) into r3
mr 3, 31
@ -61,13 +68,3 @@ bctrl
# mov SYS_exit into r0 (the exit param is already in r3)
li 0, 1
sc
2:
# restore stack
lwz 30, 0(1)
lwz 31, 4(1)
addi 1, 1, 16
blr

View File

@ -15,12 +15,12 @@ __clone:
mov %rcx,(%rsi)
syscall
test %eax,%eax
jnz 1f
xor %ebp,%ebp
jz 1f
ret
1: xor %ebp,%ebp
pop %rdi
call *%r9
mov %eax,%edi
movl $0x4000003c,%eax /* SYS_exit */
syscall
hlt
1: ret

View File

@ -16,8 +16,9 @@ __clone:
mov %rcx,(%rsi)
syscall
test %eax,%eax
jnz 1f
xor %ebp,%ebp
jz 1f
ret
1: xor %ebp,%ebp
pop %rdi
call *%r9
mov %eax,%edi
@ -25,4 +26,3 @@ __clone:
mov $60,%al
syscall
hlt
1: ret