From c666ebb1f8aac440a4d0d554e9f8aa836bf58060 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20R=C3=B8nne=20Petersen?= Date: Wed, 13 Nov 2024 09:18:37 +0100 Subject: [PATCH] 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. --- lib/libc/musl/src/thread/aarch64/clone.s | 3 ++- lib/libc/musl/src/thread/arm/clone.s | 3 ++- lib/libc/musl/src/thread/i386/clone.s | 17 ++++++++-------- lib/libc/musl/src/thread/loongarch64/clone.s | 1 + lib/libc/musl/src/thread/m68k/clone.s | 3 ++- lib/libc/musl/src/thread/microblaze/clone.s | 3 ++- lib/libc/musl/src/thread/mips/clone.s | 3 ++- lib/libc/musl/src/thread/mips64/clone.s | 3 ++- lib/libc/musl/src/thread/mipsn32/clone.s | 3 ++- lib/libc/musl/src/thread/or1k/clone.s | 3 ++- lib/libc/musl/src/thread/powerpc/clone.s | 21 +++++++++----------- lib/libc/musl/src/thread/x32/clone.s | 6 +++--- lib/libc/musl/src/thread/x86_64/clone.s | 6 +++--- 13 files changed, 40 insertions(+), 35 deletions(-) diff --git a/lib/libc/musl/src/thread/aarch64/clone.s b/lib/libc/musl/src/thread/aarch64/clone.s index e3c83395ca..9ac272bde3 100644 --- a/lib/libc/musl/src/thread/aarch64/clone.s +++ b/lib/libc/musl/src/thread/aarch64/clone.s @@ -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 diff --git a/lib/libc/musl/src/thread/arm/clone.s b/lib/libc/musl/src/thread/arm/clone.s index bb0965dafe..4ff0c0e88b 100644 --- a/lib/libc/musl/src/thread/arm/clone.s +++ b/lib/libc/musl/src/thread/arm/clone.s @@ -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 diff --git a/lib/libc/musl/src/thread/i386/clone.s b/lib/libc/musl/src/thread/i386/clone.s index e237d3c632..f89ddd9d53 100644 --- a/lib/libc/musl/src/thread/i386/clone.s +++ b/lib/libc/musl/src/thread/i386/clone.s @@ -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 diff --git a/lib/libc/musl/src/thread/loongarch64/clone.s b/lib/libc/musl/src/thread/loongarch64/clone.s index a165b365a3..cb4aacfc6d 100644 --- a/lib/libc/musl/src/thread/loongarch64/clone.s +++ b/lib/libc/musl/src/thread/loongarch64/clone.s @@ -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 diff --git a/lib/libc/musl/src/thread/m68k/clone.s b/lib/libc/musl/src/thread/m68k/clone.s index f6dfa06f49..42ec19f724 100644 --- a/lib/libc/musl/src/thread/m68k/clone.s +++ b/lib/libc/musl/src/thread/m68k/clone.s @@ -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 diff --git a/lib/libc/musl/src/thread/microblaze/clone.s b/lib/libc/musl/src/thread/microblaze/clone.s index b68cc5fc22..64e3f0743f 100644 --- a/lib/libc/musl/src/thread/microblaze/clone.s +++ b/lib/libc/musl/src/thread/microblaze/clone.s @@ -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 diff --git a/lib/libc/musl/src/thread/mips/clone.s b/lib/libc/musl/src/thread/mips/clone.s index 0446338568..229b987e96 100644 --- a/lib/libc/musl/src/thread/mips/clone.s +++ b/lib/libc/musl/src/thread/mips/clone.s @@ -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 diff --git a/lib/libc/musl/src/thread/mips64/clone.s b/lib/libc/musl/src/thread/mips64/clone.s index 2d86899a1d..8de3db6c4e 100644 --- a/lib/libc/musl/src/thread/mips64/clone.s +++ b/lib/libc/musl/src/thread/mips64/clone.s @@ -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 diff --git a/lib/libc/musl/src/thread/mipsn32/clone.s b/lib/libc/musl/src/thread/mipsn32/clone.s index 4d3c8c7a25..9571231a62 100644 --- a/lib/libc/musl/src/thread/mipsn32/clone.s +++ b/lib/libc/musl/src/thread/mipsn32/clone.s @@ -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 diff --git a/lib/libc/musl/src/thread/or1k/clone.s b/lib/libc/musl/src/thread/or1k/clone.s index 2473ac2040..05c55c6982 100644 --- a/lib/libc/musl/src/thread/or1k/clone.s +++ b/lib/libc/musl/src/thread/or1k/clone.s @@ -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) diff --git a/lib/libc/musl/src/thread/powerpc/clone.s b/lib/libc/musl/src/thread/powerpc/clone.s index da13f446c0..019fd62a95 100644 --- a/lib/libc/musl/src/thread/powerpc/clone.s +++ b/lib/libc/musl/src/thread/powerpc/clone.s @@ -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 - diff --git a/lib/libc/musl/src/thread/x32/clone.s b/lib/libc/musl/src/thread/x32/clone.s index b870880f93..d713452676 100644 --- a/lib/libc/musl/src/thread/x32/clone.s +++ b/lib/libc/musl/src/thread/x32/clone.s @@ -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 diff --git a/lib/libc/musl/src/thread/x86_64/clone.s b/lib/libc/musl/src/thread/x86_64/clone.s index 6e47bc0a37..3c30220e50 100644 --- a/lib/libc/musl/src/thread/x86_64/clone.s +++ b/lib/libc/musl/src/thread/x86_64/clone.s @@ -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