Disable stack protector for __libc_preinit
__libc_preinit sets up the stack protector global cookie value, and thus cannot intialize a stack protector cookie for itself in the function prologue. LTO compilation can inline functions requiring a stack protector into __libc_preinit. This patch disables stack protection for __libc_preinit and forces all potentially inlined functions into a helper that can have a stack protector. Test: run bionic-unit-tests Change-Id: I45911611190f216c91eb6feff722967214c5f99f
This commit is contained in:
parent
d411524609
commit
f4b1cbda4a
|
@ -123,6 +123,12 @@ cc_library_static {
|
|||
cflags: ["-fno-stack-protector"],
|
||||
}
|
||||
|
||||
cc_library_static {
|
||||
name: "libc_init_dynamic",
|
||||
defaults: ["libc_defaults"],
|
||||
srcs: ["bionic/libc_init_dynamic.cpp"],
|
||||
cflags: ["-fno-stack-protector"],
|
||||
}
|
||||
|
||||
// ========================================================
|
||||
// libc_tzcode.a - upstream 'tzcode' code
|
||||
|
@ -1757,10 +1763,10 @@ cc_library {
|
|||
"arch-common/bionic/crtbrand.S",
|
||||
"bionic/icu.cpp",
|
||||
"bionic/malloc_common.cpp",
|
||||
"bionic/libc_init_dynamic.cpp",
|
||||
"bionic/NetdClient.cpp",
|
||||
"arch-common/bionic/crtend_so.S",
|
||||
],
|
||||
whole_static_libs: ["libc_init_dynamic"],
|
||||
},
|
||||
|
||||
required: ["tzdata"],
|
||||
|
|
|
@ -61,6 +61,21 @@ extern "C" {
|
|||
extern int __cxa_atexit(void (*)(void *), void *, void *);
|
||||
};
|
||||
|
||||
// We need a helper function for __libc_preinit because compiling with LTO may
|
||||
// inline functions requiring a stack protector check, but __stack_chk_guard is
|
||||
// not initialized at the start of __libc_preinit. __libc_preinit_impl will run
|
||||
// after __stack_chk_guard is initialized and therefore can safely have a stack
|
||||
// protector.
|
||||
__attribute__((noinline))
|
||||
static void __libc_preinit_impl(KernelArgumentBlock& args) {
|
||||
__libc_init_globals(args);
|
||||
__libc_init_common(args);
|
||||
|
||||
// Hooks for various libraries to let them know that we're starting up.
|
||||
__libc_globals.mutate(__libc_init_malloc);
|
||||
netdClientInit();
|
||||
}
|
||||
|
||||
// We flag the __libc_preinit function as a constructor to ensure
|
||||
// that its address is listed in libc.so's .init_array section.
|
||||
// This ensures that the function is called by the dynamic linker
|
||||
|
@ -79,12 +94,7 @@ __attribute__((constructor)) static void __libc_preinit() {
|
|||
// thread's TLS slot with that value. Initialize the local global stack guard with its value.
|
||||
__stack_chk_guard = reinterpret_cast<uintptr_t>(tls[TLS_SLOT_STACK_GUARD]);
|
||||
|
||||
__libc_init_globals(*args);
|
||||
__libc_init_common(*args);
|
||||
|
||||
// Hooks for various libraries to let them know that we're starting up.
|
||||
__libc_globals.mutate(__libc_init_malloc);
|
||||
netdClientInit();
|
||||
__libc_preinit_impl(*args);
|
||||
}
|
||||
|
||||
// This function is called from the executable's _start entry point
|
||||
|
|
Loading…
Reference in New Issue