diff options
author | Elliott Hughes | 2014-12-10 13:08:47 -0600 |
---|---|---|
committer | Elliott Hughes | 2014-12-10 13:08:47 -0600 |
commit | 51f5d83237ce104655f1bc05576ed8ebf64e97cc (patch) | |
tree | a773abbc92ce4a1649dcea6bf07edecb5886958a | |
parent | 0952a5540e8bb6ceb74389601b9088398d585771 (diff) | |
download | platform-bionic-51f5d83237ce104655f1bc05576ed8ebf64e97cc.tar.gz platform-bionic-51f5d83237ce104655f1bc05576ed8ebf64e97cc.tar.xz platform-bionic-51f5d83237ce104655f1bc05576ed8ebf64e97cc.zip |
Fix arm64 clone stack handling.
Make sure we adjust the stack pointer so a signal can't overwrite data.
Bug: 15195265
Change-Id: I5ab9469a82cb214c32f40a713268a1ab74a4c6fa
-rw-r--r-- | libc/arch-arm/bionic/__bionic_clone.S | 7 | ||||
-rw-r--r-- | libc/arch-arm64/bionic/__bionic_clone.S | 16 |
2 files changed, 13 insertions, 10 deletions
diff --git a/libc/arch-arm/bionic/__bionic_clone.S b/libc/arch-arm/bionic/__bionic_clone.S index b02a7099..a268f9d1 100644 --- a/libc/arch-arm/bionic/__bionic_clone.S +++ b/libc/arch-arm/bionic/__bionic_clone.S | |||
@@ -42,12 +42,14 @@ ENTRY(__bionic_clone) | |||
42 | # load extra parameters | 42 | # load extra parameters |
43 | ldmfd ip, {r4, r5, r6} | 43 | ldmfd ip, {r4, r5, r6} |
44 | 44 | ||
45 | # store 'fn' and 'arg' to the child stack | 45 | # Push 'fn' and 'arg' onto the child stack. |
46 | stmdb r1!, {r5, r6} | 46 | stmdb r1!, {r5, r6} |
47 | 47 | ||
48 | # System call | 48 | # Make the system call. |
49 | ldr r7, =__NR_clone | 49 | ldr r7, =__NR_clone |
50 | swi #0 | 50 | swi #0 |
51 | |||
52 | # Are we the child? | ||
51 | movs r0, r0 | 53 | movs r0, r0 |
52 | beq 1f | 54 | beq 1f |
53 | 55 | ||
@@ -61,6 +63,7 @@ ENTRY(__bionic_clone) | |||
61 | 1: # The child. | 63 | 1: # The child. |
62 | # Setting lr to 0 will make the unwinder stop at __start_thread | 64 | # Setting lr to 0 will make the unwinder stop at __start_thread |
63 | mov lr, #0 | 65 | mov lr, #0 |
66 | # Call __start_thread with the 'fn' and 'arg' we stored on the child stack. | ||
64 | pop {r0, r1} | 67 | pop {r0, r1} |
65 | b __start_thread | 68 | b __start_thread |
66 | END(__bionic_clone) | 69 | END(__bionic_clone) |
diff --git a/libc/arch-arm64/bionic/__bionic_clone.S b/libc/arch-arm64/bionic/__bionic_clone.S index 56ac0f69..27e44e7f 100644 --- a/libc/arch-arm64/bionic/__bionic_clone.S +++ b/libc/arch-arm64/bionic/__bionic_clone.S | |||
@@ -31,8 +31,8 @@ | |||
31 | // pid_t __bionic_clone(int flags, void* child_stack, pid_t* parent_tid, void* tls, pid_t* child_tid, int (*fn)(void*), void* arg); | 31 | // pid_t __bionic_clone(int flags, void* child_stack, pid_t* parent_tid, void* tls, pid_t* child_tid, int (*fn)(void*), void* arg); |
32 | 32 | ||
33 | ENTRY(__bionic_clone) | 33 | ENTRY(__bionic_clone) |
34 | # Copy 'fn' and 'arg' onto the child stack. | 34 | # Push 'fn' and 'arg' onto the child stack. |
35 | stp x5, x6, [x1, #-16] | 35 | stp x5, x6, [x1, #-16]! |
36 | 36 | ||
37 | # Make the system call. | 37 | # Make the system call. |
38 | mov x8, __NR_clone | 38 | mov x8, __NR_clone |
@@ -49,12 +49,12 @@ ENTRY(__bionic_clone) | |||
49 | ret | 49 | ret |
50 | 50 | ||
51 | .L_bc_child: | 51 | .L_bc_child: |
52 | # We're in the child now. Set the end of the frame record chain... | 52 | # We're in the child now. Set the end of the frame record chain. |
53 | mov x29, xzr | 53 | mov x29, #0 |
54 | # Setting x30 to 0 will make the unwinder stop at __start_thread | 54 | # Setting x30 to 0 will make the unwinder stop at __start_thread. |
55 | mov x30, xzr | 55 | mov x30, #0 |
56 | # ...and call __start_thread with the 'fn' and 'arg' we stored on the child stack. | 56 | # Call __start_thread with the 'fn' and 'arg' we stored on the child stack. |
57 | ldp x0, x1, [sp, #-16] | 57 | ldp x0, x1, [sp], #16 |
58 | b __start_thread | 58 | b __start_thread |
59 | END(__bionic_clone) | 59 | END(__bionic_clone) |
60 | .hidden __bionic_clone | 60 | .hidden __bionic_clone |