From 8df0fe0c74b7af819f36e37ec9b924fdd22c8ba4 Mon Sep 17 00:00:00 2001 From: Ben Cheng Date: Fri, 23 May 2014 16:35:21 -0700 Subject: [PATCH] Clear link register in __bionic_clone. Since __bionic_clone uses tail-call to invoke __bionic_clone_entry, at runtime the unwinder will reach the stack of the clone() function, which belongs to the parent thread, if the link register is not cleared. BUG: 14270816 Change-Id: Ia3711c87f8b619debe73748c28b9fb8691ea698e --- libc/arch-arm/bionic/__bionic_clone.S | 9 ++------- libc/arch-arm64/bionic/__bionic_clone.S | 4 ++-- 2 files changed, 4 insertions(+), 9 deletions(-) diff --git a/libc/arch-arm/bionic/__bionic_clone.S b/libc/arch-arm/bionic/__bionic_clone.S index 7cc4db56b..2643ae00d 100644 --- a/libc/arch-arm/bionic/__bionic_clone.S +++ b/libc/arch-arm/bionic/__bionic_clone.S @@ -54,19 +54,14 @@ ENTRY(__bionic_clone) # In the parent, reload saved registers then either return or set errno. ldmfd sp!, {r4, r5, r6, r7} - .cfi_def_cfa_offset 0 cmn r0, #(MAX_ERRNO + 1) bxls lr neg r0, r0 b __set_errno 1: # The child. - # Re-add the unwind directives that were reset from above. - .cfi_def_cfa_offset 16 - .cfi_rel_offset r4, 0 - .cfi_rel_offset r5, 4 - .cfi_rel_offset r6, 8 - .cfi_rel_offset r7, 12 + # Setting lr to 0 will make the unwinder stop at __bionic_clone_entry + mov lr, #0 ldr r0, [sp, #-4] ldr r1, [sp, #-8] b __bionic_clone_entry diff --git a/libc/arch-arm64/bionic/__bionic_clone.S b/libc/arch-arm64/bionic/__bionic_clone.S index c49782cf0..d3c03742d 100644 --- a/libc/arch-arm64/bionic/__bionic_clone.S +++ b/libc/arch-arm64/bionic/__bionic_clone.S @@ -61,9 +61,9 @@ ENTRY(__bionic_clone) .L_bc_child: # We're in the child now. Set the end of the frame record chain... - .cfi_undefined x29 - .cfi_undefined x30 mov x29, xzr + # Setting x30 to 0 will make the unwinder stop at __bionic_clone_entry + mov x30, xzr # ...and call __bionic_clone_entry with the 'fn' and 'arg' we stored on the child stack. ldp x0, x1, [sp, #-16] b __bionic_clone_entry