[compiler-rt] d7bead8 - [sanitizer] Remove crypt and crypt_r interceptors

Fangrui Song via llvm-commits llvm-commits at lists.llvm.org
Fri Apr 28 09:59:23 PDT 2023


Author: Fangrui Song
Date: 2023-04-28T09:59:17-07:00
New Revision: d7bead833631486e337e541e692d9b4a1ca14edd

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

LOG: [sanitizer] Remove crypt and crypt_r interceptors

>From Florian Weimer's D144073

> On GNU/Linux (glibc), the crypt and crypt_r functions are not part of the main shared object (libc.so.6), but libcrypt (with multiple possible sonames). The sanitizer libraries do not depend on libcrypt, so it can happen that during sanitizer library initialization, no real implementation will be found because the crypt, crypt_r functions are not present in the process image (yet). If its interceptors are called nevertheless, this results in a call through a null pointer when the sanitizer library attempts to forward the call to the real implementation.
>
> Many distributions have already switched to libxcrypt, a library that is separate from glibc and that can be build with sanitizers directly (avoiding the need for interceptors). This patch disables building the interceptor for glibc targets.

Let's remove crypt and crypt_r interceptors (D68431) to fix issues with
newer glibc.

For older glibc, msan will not know that an uninstrumented crypt_r call
initializes `data`, so there is a risk for false positives. However, with some
codebase survey, I think crypt_r uses are very few and the call sites typically
have a `memset(&data, 0, sizeof(data));` anyway.

Fix https://github.com/google/sanitizers/issues/1365
Related: https://bugzilla.redhat.com/show_bug.cgi?id=2169432

Reviewed By: #sanitizers, fweimer, thesamesam, vitalybuka

Differential Revision: https://reviews.llvm.org/D149403

Added: 
    

Modified: 
    compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc
    compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h
    compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.cpp
    compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h

Removed: 
    compiler-rt/test/sanitizer_common/TestCases/Linux/crypt_r.cpp
    compiler-rt/test/sanitizer_common/TestCases/Posix/crypt.cpp


################################################################################
diff  --git a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc
index b30c91f06cfeb..490a8b12d8b17 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc
@@ -10086,41 +10086,6 @@ INTERCEPTOR(SSIZE_T, getrandom, void *buf, SIZE_T buflen, unsigned int flags) {
 #define INIT_GETRANDOM
 #endif
 
-#if SANITIZER_INTERCEPT_CRYPT
-INTERCEPTOR(char *, crypt, char *key, char *salt) {
-  void *ctx;
-  COMMON_INTERCEPTOR_ENTER(ctx, crypt, key, salt);
-  COMMON_INTERCEPTOR_READ_RANGE(ctx, key, internal_strlen(key) + 1);
-  COMMON_INTERCEPTOR_READ_RANGE(ctx, salt, internal_strlen(salt) + 1);
-  char *res = REAL(crypt)(key, salt);
-  if (res != nullptr)
-    COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, internal_strlen(res) + 1);
-  return res;
-}
-#define INIT_CRYPT COMMON_INTERCEPT_FUNCTION(crypt);
-#else
-#define INIT_CRYPT
-#endif
-
-#if SANITIZER_INTERCEPT_CRYPT_R
-INTERCEPTOR(char *, crypt_r, char *key, char *salt, void *data) {
-  void *ctx;
-  COMMON_INTERCEPTOR_ENTER(ctx, crypt_r, key, salt, data);
-  COMMON_INTERCEPTOR_READ_RANGE(ctx, key, internal_strlen(key) + 1);
-  COMMON_INTERCEPTOR_READ_RANGE(ctx, salt, internal_strlen(salt) + 1);
-  char *res = REAL(crypt_r)(key, salt, data);
-  if (res != nullptr) {
-    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data,
-                                   __sanitizer::struct_crypt_data_sz);
-    COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, internal_strlen(res) + 1);
-  }
-  return res;
-}
-#define INIT_CRYPT_R COMMON_INTERCEPT_FUNCTION(crypt_r);
-#else
-#define INIT_CRYPT_R
-#endif
-
 #if SANITIZER_INTERCEPT_GETENTROPY
 INTERCEPTOR(int, getentropy, void *buf, SIZE_T buflen) {
   void *ctx;
@@ -10698,8 +10663,6 @@ static void InitializeCommonInterceptors() {
   INIT_GETUSERSHELL;
   INIT_SL_INIT;
   INIT_GETRANDOM;
-  INIT_CRYPT;
-  INIT_CRYPT_R;
   INIT_GETENTROPY;
   INIT_QSORT;
   INIT_QSORT_R;

diff  --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h b/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h
index eb39fabfd5983..c82ab5c210562 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h
@@ -569,8 +569,6 @@
 #define SANITIZER_INTERCEPT_FDEVNAME SI_FREEBSD
 #define SANITIZER_INTERCEPT_GETUSERSHELL (SI_POSIX && !SI_ANDROID)
 #define SANITIZER_INTERCEPT_SL_INIT (SI_FREEBSD || SI_NETBSD)
-#define SANITIZER_INTERCEPT_CRYPT (SI_POSIX && !SI_ANDROID)
-#define SANITIZER_INTERCEPT_CRYPT_R (SI_LINUX && !SI_ANDROID)
 
 #define SANITIZER_INTERCEPT_GETRANDOM \
   ((SI_LINUX && __GLIBC_PREREQ(2, 25)) || SI_FREEBSD)

diff  --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.cpp
index a04eed7aa5a6e..6d61d276d77e3 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.cpp
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.cpp
@@ -177,10 +177,6 @@ typedef struct user_fpregs elf_fpregset_t;
 #  include "sanitizer_platform_interceptors.h"
 #  include "sanitizer_platform_limits_posix.h"
 
-#if SANITIZER_INTERCEPT_CRYPT_R
-#include <crypt.h>
-#endif
-
 namespace __sanitizer {
   unsigned struct_utsname_sz = sizeof(struct utsname);
   unsigned struct_stat_sz = sizeof(struct stat);
@@ -300,10 +296,6 @@ namespace __sanitizer {
   unsigned struct_statvfs64_sz = sizeof(struct statvfs64);
 #endif // SANITIZER_GLIBC
 
-#if SANITIZER_INTERCEPT_CRYPT_R
-  unsigned struct_crypt_data_sz = sizeof(struct crypt_data);
-#endif
-
 #if SANITIZER_LINUX && !SANITIZER_ANDROID
   unsigned struct_timex_sz = sizeof(struct timex);
   unsigned struct_msqid_ds_sz = sizeof(struct msqid_ds);

diff  --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h
index e6f298c26e1fb..58244c9944a03 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h
@@ -309,7 +309,6 @@ extern unsigned struct_msqid_ds_sz;
 extern unsigned struct_mq_attr_sz;
 extern unsigned struct_timex_sz;
 extern unsigned struct_statvfs_sz;
-extern unsigned struct_crypt_data_sz;
 #endif  // SANITIZER_LINUX && !SANITIZER_ANDROID
 
 struct __sanitizer_iovec {

diff  --git a/compiler-rt/test/sanitizer_common/TestCases/Linux/crypt_r.cpp b/compiler-rt/test/sanitizer_common/TestCases/Linux/crypt_r.cpp
deleted file mode 100644
index 69bfb46aa5f17..0000000000000
--- a/compiler-rt/test/sanitizer_common/TestCases/Linux/crypt_r.cpp
+++ /dev/null
@@ -1,36 +0,0 @@
-// RUN: %clangxx -O0 -g %s -lcrypt -o %t && %run %t
-
-// crypt.h is missing from Android.
-// UNSUPPORTED: android
-
-#include <assert.h>
-#include <unistd.h>
-#include <cstring>
-#include <crypt.h>
-
-int main(int argc, char **argv) {
-  {
-    crypt_data cd;
-    cd.initialized = 0;
-    char *p = crypt_r("abcdef", "xz", &cd);
-    volatile size_t z = strlen(p);
-  }
-  {
-    crypt_data cd;
-    cd.initialized = 0;
-    char *p = crypt_r("abcdef", "$1$", &cd);
-    volatile size_t z = strlen(p);
-  }
-  {
-    crypt_data cd;
-    cd.initialized = 0;
-    char *p = crypt_r("abcdef", "$5$", &cd);
-    volatile size_t z = strlen(p);
-  }
-  {
-    crypt_data cd;
-    cd.initialized = 0;
-    char *p = crypt_r("abcdef", "$6$", &cd);
-    volatile size_t z = strlen(p);
-  }
-}

diff  --git a/compiler-rt/test/sanitizer_common/TestCases/Posix/crypt.cpp b/compiler-rt/test/sanitizer_common/TestCases/Posix/crypt.cpp
deleted file mode 100644
index 3a8faaa1ae768..0000000000000
--- a/compiler-rt/test/sanitizer_common/TestCases/Posix/crypt.cpp
+++ /dev/null
@@ -1,32 +0,0 @@
-// RUN: %clangxx -O0 -g %s -o %t -lcrypt && %run %t
-
-// crypt() is missing from Android and -lcrypt from darwin.
-// UNSUPPORTED: android, darwin
-
-#include <assert.h>
-#include <unistd.h>
-#include <cstring>
-#if __has_include(<crypt.h>)
-#include <crypt.h>
-#endif
-
-int
-main (int argc, char** argv)
-{
-  {
-    char *p = crypt("abcdef", "xz");
-    volatile size_t z = strlen(p);
-  }
-  {
-    char *p = crypt("abcdef", "$1$");
-    volatile size_t z = strlen(p);
-  }
-  {
-    char *p = crypt("abcdef", "$5$");
-    volatile size_t z = strlen(p);
-  }
-  {
-    char *p = crypt("abcdef", "$6$");
-    volatile size_t z = strlen(p);
-  }
-}


        


More information about the llvm-commits mailing list