diff --git a/libc/bionic/libc_init_common.cpp b/libc/bionic/libc_init_common.cpp index 9b23ece5a..bd716286a 100644 --- a/libc/bionic/libc_init_common.cpp +++ b/libc/bionic/libc_init_common.cpp @@ -37,6 +37,7 @@ #include #include #include +#include #include #include @@ -44,6 +45,7 @@ #include "private/bionic_ssp.h" #include "private/bionic_tls.h" #include "private/KernelArgumentBlock.h" +#include "private/libc_logging.h" #include "pthread_internal.h" extern "C" abort_msg_t** __abort_message_ptr; @@ -289,6 +291,19 @@ static void __sanitize_environment_variables(char** env) { dst[0] = nullptr; } +static void __initialize_personality() { +#if !defined(__LP64__) + int old_value = personality(0xffffffff); + if (old_value == -1) { + __libc_fatal("error getting old personality value: %s", strerror(errno)); + } + + if (personality((static_cast(old_value) & ~PER_MASK) | PER_LINUX32) == -1) { + __libc_fatal("error setting PER_LINUX32 personality: %s", strerror(errno)); + } +#endif +} + void __libc_init_AT_SECURE(KernelArgumentBlock& args) { __libc_auxv = args.auxv; @@ -312,6 +327,8 @@ void __libc_init_AT_SECURE(KernelArgumentBlock& args) { // Now the environment has been sanitized, make it available. environ = args.envp; + + __initialize_personality(); } /* This function will be called during normal program termination diff --git a/libc/include/sys/personality.h b/libc/include/sys/personality.h index 8a023f967..776446856 100644 --- a/libc/include/sys/personality.h +++ b/libc/include/sys/personality.h @@ -34,7 +34,7 @@ __BEGIN_DECLS -extern int personality (unsigned long persona); +extern int personality (unsigned int persona); __END_DECLS diff --git a/linker/linker.cpp b/linker/linker.cpp index c6e569a50..611edb36a 100644 --- a/linker/linker.cpp +++ b/linker/linker.cpp @@ -37,7 +37,6 @@ #include #include #include -#include #include #include @@ -3181,12 +3180,6 @@ static ElfW(Addr) __linker_init_post_relocation(KernelArgumentBlock& args, ElfW( ldpreload_env = getenv("LD_PRELOAD"); } -#if !defined(__LP64__) - if (personality(PER_LINUX32) == -1) { - __libc_fatal("error setting PER_LINUX32 personality: %s", strerror(errno)); - } -#endif - INFO("[ android linker & debugger ]"); soinfo* si = soinfo_alloc(args.argv[0], nullptr, 0, RTLD_GLOBAL); diff --git a/tests/sys_personality_test.cpp b/tests/sys_personality_test.cpp index 55a023dfa..2dfaa658c 100644 --- a/tests/sys_personality_test.cpp +++ b/tests/sys_personality_test.cpp @@ -19,7 +19,7 @@ #include TEST(sys_personality, current_persona) { - int persona = personality(0xffffffff); + int persona = personality(0xffffffff) & PER_MASK; #if defined(__BIONIC__) #if defined(__LP64__) ASSERT_EQ(PER_LINUX, persona);