From 172955a4e30b88ce8239a7ef426b4e8903e9923c Mon Sep 17 00:00:00 2001 From: Christopher Ferris Date: Tue, 26 Aug 2014 20:48:11 -0700 Subject: [PATCH] Replace snprintf calls in linker. When enabling debug malloc, the snprintf calls in the linker fails to update the buffer. The problem is that snprintf makes a call to pthread_getspecific that returns a valid pointer, but the data it points to is zero. This should never happen and causes the snprintf to stop and do nothing. Temporarily replace snprintf with a different implementation to work around this issue. Bug: 16874447 Bug: 17302493 Change-Id: I7a500f28adf153150cf2812fae745ff41f1c48d3 --- linker/debugger.cpp | 4 ++-- linker/linker.cpp | 16 +++++++++++++++- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/linker/debugger.cpp b/linker/debugger.cpp index 079682cab..c31615171 100644 --- a/linker/debugger.cpp +++ b/linker/debugger.cpp @@ -170,9 +170,9 @@ static void log_signal_summary(int signum, const siginfo_t* info) { if (info != NULL) { // For a rethrown signal, this si_code will be right and the one debuggerd shows will // always be SI_TKILL. - snprintf(code_desc, sizeof(code_desc), ", code %d", info->si_code); + __libc_format_buffer(code_desc, sizeof(code_desc), ", code %d", info->si_code); if (has_address) { - snprintf(addr_desc, sizeof(addr_desc), ", fault addr %p", info->si_addr); + __libc_format_buffer(addr_desc, sizeof(addr_desc), ", fault addr %p", info->si_addr); } } __libc_format_log(ANDROID_LOG_FATAL, "libc", diff --git a/linker/linker.cpp b/linker/linker.cpp index 52eb56ab8..2d8e07eb4 100644 --- a/linker/linker.cpp +++ b/linker/linker.cpp @@ -866,7 +866,21 @@ static void soinfo_unload(soinfo* si) { } void do_android_get_LD_LIBRARY_PATH(char* buffer, size_t buffer_size) { - snprintf(buffer, buffer_size, "%s:%s", kDefaultLdPaths[0], kDefaultLdPaths[1]); + // Use basic string manipulation calls to avoid snprintf. + // snprintf indirectly calls pthread_getspecific to get the size of a buffer. + // When debug malloc is enabled, this call returns 0. This in turn causes + // snprintf to do nothing, which causes libraries to fail to load. + // See b/17302493 for further details. + // Once the above bug is fixed, this code can be modified to use + // snprintf again. + size_t required_len = strlen(kDefaultLdPaths[0]) + strlen(kDefaultLdPaths[1]) + 2; + if (buffer_size < required_len) { + __libc_fatal("android_get_LD_LIBRARY_PATH failed, buffer too small: buffer len %zu, required len %zu", + buffer_size, required_len); + } + char* end = stpcpy(buffer, kDefaultLdPaths[0]); + *end = ':'; + strcpy(end + 1, kDefaultLdPaths[1]); } void do_android_update_LD_LIBRARY_PATH(const char* ld_library_path) {