From 6c54ddd20f663de9e383fcd7b4cff93471369d87 Mon Sep 17 00:00:00 2001 From: Elliott Hughes Date: Tue, 8 Dec 2015 12:43:13 -0800 Subject: [PATCH] Fix -fstack-protector-strong for x86. We need to ensure %gs:20 is set up early enough for -fstack-protector-strong on x86, and that __set_tls doesn't get stack protector checks because it's a prerequisite for them. x86 devices/emulators won't boot without this. Bug: http://b/26073874 Change-Id: Icf0d34294648cc0c8cb406a3617befe0d45c525a --- libc/Android.mk | 3 +++ libc/arch-x86/x86.mk | 1 - libc/bionic/libc_init_common.cpp | 5 ++++- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/libc/Android.mk b/libc/Android.mk index ba3e5aa4e..456527a11 100644 --- a/libc/Android.mk +++ b/libc/Android.mk @@ -697,6 +697,9 @@ endef include $(CLEAR_VARS) LOCAL_SRC_FILES := bionic/__stack_chk_fail.cpp +# On x86, the __set_tls implementation is complex enough that +# -fstack-protector-strong inserts a check. +LOCAL_SRC_FILES_x86 := arch-x86/bionic/__set_tls.c LOCAL_CFLAGS := $(libc_common_cflags) -fno-stack-protector LOCAL_CONLYFLAGS := $(libc_common_conlyflags) LOCAL_CPPFLAGS := $(libc_common_cppflags) diff --git a/libc/arch-x86/x86.mk b/libc/arch-x86/x86.mk index b4056bbbc..1d717aa79 100644 --- a/libc/arch-x86/x86.mk +++ b/libc/arch-x86/x86.mk @@ -109,7 +109,6 @@ libc_bionic_src_files_x86 += \ arch-x86/bionic/libgcc_compat.c \ arch-x86/bionic/__restore.S \ arch-x86/bionic/setjmp.S \ - arch-x86/bionic/__set_tls.c \ arch-x86/bionic/syscall.S \ arch-x86/bionic/vfork.S \ diff --git a/libc/bionic/libc_init_common.cpp b/libc/bionic/libc_init_common.cpp index 8f1ee9569..b0c62d681 100644 --- a/libc/bionic/libc_init_common.cpp +++ b/libc/bionic/libc_init_common.cpp @@ -79,6 +79,10 @@ void __libc_init_main_thread(KernelArgumentBlock& args) { static pthread_internal_t main_thread; + // The x86 -fstack-protector implementation uses TLS, so make sure that's + // set up before we call any function that might get a stack check inserted. + __set_tls(main_thread.tls); + // Tell the kernel to clear our tid field when we exit, so we're like any other pthread. // As a side-effect, this tells us our pid (which is the same as the main thread's tid). main_thread.tid = __set_tid_address(&main_thread.tid); @@ -97,7 +101,6 @@ void __libc_init_main_thread(KernelArgumentBlock& args) { __init_thread(&main_thread); __init_tls(&main_thread); - __set_tls(main_thread.tls); // Store a pointer to the kernel argument block in a TLS slot to be // picked up by the libc constructor. -- 2.11.0