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 | 23 ++++++++++---------- 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, 43 insertions(+), 38 deletions(-) diff --git a/lib/libc/musl/src/thread/aarch64/clone.s b/lib/libc/musl/src/thread/aarch64/clone.s index e3c83395cad25634fbd6597aef8f7dc2e74046d5..9ac272bde3e6199b65ed760378a65afa6824d780 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 bb0965dafe8298e652a5291dd443893153c748af..4ff0c0e88b1d8892f914fc3b1703a1bf8a13239a 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 e237d3c6324b984601048c07d8b7976b6c6e601a..f89ddd9d5314d1b7bc28812c6008dd4abf72b5ef 100644 --- a/lib/libc/musl/src/thread/i386/clone.s +++ b/lib/libc/musl/src/thread/i386/clone.s @@ -30,20 +30,19 @@ __clone: mov 8(%ebp),%ebp int $128 test %eax,%eax - jnz 1f - - mov %ebp,%eax - xor %ebp,%ebp - call *%eax - mov %eax,%ebx - xor %eax,%eax - inc %eax - int $128 - hlt - -1: add $16,%esp + jz 1f + add $16,%esp pop %edi pop %esi pop %ebx pop %ebp ret + +1: mov %ebp,%eax + xor %ebp,%ebp + call *%eax + mov %eax,%ebx + xor %eax,%eax + inc %eax + int $128 + hlt diff --git a/lib/libc/musl/src/thread/loongarch64/clone.s b/lib/libc/musl/src/thread/loongarch64/clone.s index a165b365a38e43178b4bbf5d381075aa9ac48197..cb4aacfc6d8980332b6f0b3ff3f8788d12f1be8d 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 f6dfa06f49daef59a7e49b2e6525ec5e800fb5c5..42ec19f7242aa38170bdce518b3a59fa05f4d1b1 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 b68cc5fc22130c1ee6460192f49a0033d133c84c..64e3f0743f6ce2a1d00c5323e60d8e6916d59a28 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 0446338568f0a8add741a32427a5b042fc1036b4..229b987e96919cc9f8ef806cd5a5833060f58b91 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 2d86899a1daa0c43991fb7e4ad07f929ad788d09..8de3db6c4e36dce0e3842bc6c1a3a26173027d3a 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 4d3c8c7a2502e96a4eafa9b0eaf2534d4e23f59f..9571231a62cfe02806ba34879eef6c9ae569cbbe 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 2473ac2040366733ca60059065a1520e7b367a1e..05c55c6982dc8742fa44b60e6cad635601d79b59 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 da13f446c03a3d134f7e0aa52c083e26ffa1c168..019fd62a95afc6e4cff64f0c5bce1e1d41ae33c8 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 b870880f93d4754f4b36e67affa388bb4784be6d..d713452676333d3e34ef9f004fcec4eebf2bcd6d 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 6e47bc0a37dee7157ceaf1369659891a2d7d16bb..3c30220e507705fbc54617517445712917d36b13 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 -- 2.54.0