OSDN Git Service

Prevent user-defined basename_r from breaking basename(3).
authorElliott Hughes <enh@google.com>
Sat, 11 Jul 2015 06:58:59 +0000 (23:58 -0700)
committerElliott Hughes <enh@google.com>
Sat, 11 Jul 2015 06:58:59 +0000 (23:58 -0700)
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

index 2f29d7b..5c27bb5 100644 (file)
@@ -39,7 +39,7 @@
 static ThreadLocalBuffer<char, MAXPATHLEN> g_basename_tls_buffer;
 static ThreadLocalBuffer<char, MAXPATHLEN> 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;
 }