[compiler-rt] 5213f30 - Revert "Problem with realpath interceptor"

Vitaly Buka via llvm-commits llvm-commits at lists.llvm.org
Wed Aug 25 13:55:26 PDT 2021


Author: Vitaly Buka
Date: 2021-08-25T13:55:23-07:00
New Revision: 5213f307abf2d2ce70c103e758f2e72b24539cb3

URL: https://github.com/llvm/llvm-project/commit/5213f307abf2d2ce70c103e758f2e72b24539cb3
DIFF: https://github.com/llvm/llvm-project/commit/5213f307abf2d2ce70c103e758f2e72b24539cb3.diff

LOG: Revert "Problem with realpath interceptor"

Breaks realpath(, nullptr) for all sanitizers.

Somehow INTERCEPT_FUNCTION and INTERCEPT_FUNCTION_VER return
false even if everything seemingly right.

And this is the issue for COMMON_INTERCEPT_FUNCTION_GLIBC_VER_MIN.
There is a check in every sanitlizer:
if (!INTERCEPT_FUNCTION_VER(name, ver) && !INTERCEPT_FUNCTION(name))

For non-versioned interceptors when INTERCEPT_FUNCTION returns false
it's not considered fatal, and it just prints a warning.

However INTERCEPT_FUNCTION_VER in this case will fallback to
INTERCEPT_FUNCTION replacing realpath with wrong version.

We need to investigate that before relanding the patch.

This reverts commit faef0d042f523357fe5590e7cb6a8391cf0351a8.

Added: 
    

Modified: 
    compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc

Removed: 
    


################################################################################
diff  --git a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc
index d008de84b29a..6c4349a52dd9 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc
@@ -3664,11 +3664,22 @@ INTERCEPTOR(char *, realpath, const char *path, char *resolved_path) {
   void *ctx;
   COMMON_INTERCEPTOR_ENTER(ctx, realpath, path, resolved_path);
   if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, internal_strlen(path) + 1);
+
+  // Workaround a bug in glibc where dlsym(RTLD_NEXT, ...) returns the oldest
+  // version of a versioned symbol. For realpath(), this gives us something
+  // (called __old_realpath) that does not handle NULL in the second argument.
+  // Handle it as part of the interceptor.
+  char *allocated_path = nullptr;
+  if (!resolved_path)
+    allocated_path = resolved_path = (char *)WRAP(malloc)(path_max + 1);
+
   char *res = REAL(realpath)(path, resolved_path);
+  if (allocated_path && !res)
+    WRAP(free)(allocated_path);
   if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, internal_strlen(res) + 1);
   return res;
 }
-#define INIT_REALPATH COMMON_INTERCEPT_FUNCTION_GLIBC_VER_MIN(realpath, "GLIBC_2.3");
+#  define INIT_REALPATH COMMON_INTERCEPT_FUNCTION(realpath);
 #else
 #define INIT_REALPATH
 #endif


        


More information about the llvm-commits mailing list