From a20a35fdda5aa4ae3c244bf7f46cdd60ab580429 Mon Sep 17 00:00:00 2001 From: Elliott Hughes Date: Fri, 10 Jul 2015 23:58:59 -0700 Subject: [PATCH] Prevent user-defined basename_r from breaking basename(3). LP64 is immune because basename_r is hidden there, but on LP32 a basename_r defined in the executable breaks basename because its call to basename_r will resolve to that one rather than the one in libc. Bug: http://b/22415484 Change-Id: Ied3ca7ad3fb0e744eb705fc924743f893b4ad490 --- libc/bionic/libgen.cpp | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/libc/bionic/libgen.cpp b/libc/bionic/libgen.cpp index 2f29d7b63..5c27bb53b 100644 --- a/libc/bionic/libgen.cpp +++ b/libc/bionic/libgen.cpp @@ -39,7 +39,7 @@ static ThreadLocalBuffer g_basename_tls_buffer; static ThreadLocalBuffer g_dirname_tls_buffer; -__LIBC64_HIDDEN__ int basename_r(const char* path, char* buffer, size_t buffer_size) { +static int __basename_r(const char* path, char* buffer, size_t buffer_size) { const char* startp = NULL; const char* endp = NULL; int len; @@ -91,7 +91,12 @@ __LIBC64_HIDDEN__ int basename_r(const char* path, char* buffer, size_t buffer_s return result; } -__LIBC64_HIDDEN__ int dirname_r(const char* path, char* buffer, size_t buffer_size) { +// Since this is a non-standard symbol, it might be hijacked by a basename_r in the executable. +__LIBC64_HIDDEN__ int basename_r(const char* path, char* buffer, size_t buffer_size) { + return __basename_r(path, buffer, buffer_size); +} + +static int __dirname_r(const char* path, char* buffer, size_t buffer_size) { const char* endp = NULL; int len; int result; @@ -150,14 +155,19 @@ __LIBC64_HIDDEN__ int dirname_r(const char* path, char* buffer, size_t buffer_si return result; } +// Since this is a non-standard symbol, it might be hijacked by a basename_r in the executable. +__LIBC64_HIDDEN__ int dirname_r(const char* path, char* buffer, size_t buffer_size) { + return __dirname_r(path, buffer, buffer_size); +} + char* basename(const char* path) { char* buf = g_basename_tls_buffer.get(); - int rc = basename_r(path, buf, g_basename_tls_buffer.size()); + int rc = __basename_r(path, buf, g_basename_tls_buffer.size()); return (rc < 0) ? NULL : buf; } char* dirname(const char* path) { char* buf = g_dirname_tls_buffer.get(); - int rc = dirname_r(path, buf, g_dirname_tls_buffer.size()); + int rc = __dirname_r(path, buf, g_dirname_tls_buffer.size()); return (rc < 0) ? NULL : buf; } -- 2.11.0