0008-Remove-crypt-and-crypt_r-interceptors.patch 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. From 0ef972d11dda9051941656e5797889b8fbf2dca6 Mon Sep 17 00:00:00 2001
  2. From: Fangrui Song <i@maskray.me>
  3. Date: Fri, 28 Apr 2023 09:59:17 -0700
  4. Subject: [PATCH] Remove crypt and crypt_r interceptors
  5. From Florian Weimer's D144073
  6. > 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.
  7. >
  8. > 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.
  9. Let's remove crypt and crypt_r interceptors (D68431) to fix issues with
  10. newer glibc.
  11. For older glibc, msan will not know that an uninstrumented crypt_r call
  12. initializes `data`, so there is a risk for false positives. However, with some
  13. codebase survey, I think crypt_r uses are very few and the call sites typically
  14. have a `memset(&data, 0, sizeof(data));` anyway.
  15. Fix https://github.com/google/sanitizers/issues/1365
  16. Related: https://bugzilla.redhat.com/show_bug.cgi?id=2169432
  17. Reviewed By: #sanitizers, fweimer, thesamesam, vitalybuka
  18. Differential Revision: https://reviews.llvm.org/D149403
  19. [Thomas: taken from Crosstool-NG]
  20. Upstream: (llvm) https://github.com/llvm/llvm-project/commit/d7bead833631486e337e541e692d9b4a1ca14edd
  21. Upstream: (gcc) https://github.com/gcc-mirror/gcc/commit/d96e14ceb9475f9bccbbc0325d5b11419fad9246
  22. Signed-off-by: Thomas Petazzoni <thomas.petazzoni@bootlin.com>
  23. ---
  24. .../sanitizer_common_interceptors.inc | 37 -------------------
  25. .../sanitizer_platform_interceptors.h | 2 -
  26. .../sanitizer_platform_limits_posix.cpp | 2 -
  27. .../sanitizer_platform_limits_posix.h | 1 -
  28. 4 files changed, 42 deletions(-)
  29. diff --git a/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc b/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc
  30. index ff2acfc7c010..6d802bc7159f 100644
  31. --- a/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc
  32. +++ b/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc
  33. @@ -9814,41 +9814,6 @@ INTERCEPTOR(SSIZE_T, getrandom, void *buf, SIZE_T buflen, unsigned int flags) {
  34. #define INIT_GETRANDOM
  35. #endif
  36. -#if SANITIZER_INTERCEPT_CRYPT
  37. -INTERCEPTOR(char *, crypt, char *key, char *salt) {
  38. - void *ctx;
  39. - COMMON_INTERCEPTOR_ENTER(ctx, crypt, key, salt);
  40. - COMMON_INTERCEPTOR_READ_RANGE(ctx, key, internal_strlen(key) + 1);
  41. - COMMON_INTERCEPTOR_READ_RANGE(ctx, salt, internal_strlen(salt) + 1);
  42. - char *res = REAL(crypt)(key, salt);
  43. - if (res != nullptr)
  44. - COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, internal_strlen(res) + 1);
  45. - return res;
  46. -}
  47. -#define INIT_CRYPT COMMON_INTERCEPT_FUNCTION(crypt);
  48. -#else
  49. -#define INIT_CRYPT
  50. -#endif
  51. -
  52. -#if SANITIZER_INTERCEPT_CRYPT_R
  53. -INTERCEPTOR(char *, crypt_r, char *key, char *salt, void *data) {
  54. - void *ctx;
  55. - COMMON_INTERCEPTOR_ENTER(ctx, crypt_r, key, salt, data);
  56. - COMMON_INTERCEPTOR_READ_RANGE(ctx, key, internal_strlen(key) + 1);
  57. - COMMON_INTERCEPTOR_READ_RANGE(ctx, salt, internal_strlen(salt) + 1);
  58. - char *res = REAL(crypt_r)(key, salt, data);
  59. - if (res != nullptr) {
  60. - COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data,
  61. - __sanitizer::struct_crypt_data_sz);
  62. - COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, internal_strlen(res) + 1);
  63. - }
  64. - return res;
  65. -}
  66. -#define INIT_CRYPT_R COMMON_INTERCEPT_FUNCTION(crypt_r);
  67. -#else
  68. -#define INIT_CRYPT_R
  69. -#endif
  70. -
  71. #if SANITIZER_INTERCEPT_GETENTROPY
  72. INTERCEPTOR(int, getentropy, void *buf, SIZE_T buflen) {
  73. void *ctx;
  74. @@ -10337,8 +10302,6 @@ static void InitializeCommonInterceptors() {
  75. INIT_GETUSERSHELL;
  76. INIT_SL_INIT;
  77. INIT_GETRANDOM;
  78. - INIT_CRYPT;
  79. - INIT_CRYPT_R;
  80. INIT_GETENTROPY;
  81. INIT_QSORT;
  82. INIT_QSORT_R;
  83. diff --git a/libsanitizer/sanitizer_common/sanitizer_platform_interceptors.h b/libsanitizer/sanitizer_common/sanitizer_platform_interceptors.h
  84. index 18bab346ce6e..cf329b76836e 100644
  85. --- a/libsanitizer/sanitizer_common/sanitizer_platform_interceptors.h
  86. +++ b/libsanitizer/sanitizer_common/sanitizer_platform_interceptors.h
  87. @@ -572,8 +572,6 @@
  88. #define SANITIZER_INTERCEPT_FDEVNAME SI_FREEBSD
  89. #define SANITIZER_INTERCEPT_GETUSERSHELL (SI_POSIX && !SI_ANDROID)
  90. #define SANITIZER_INTERCEPT_SL_INIT (SI_FREEBSD || SI_NETBSD)
  91. -#define SANITIZER_INTERCEPT_CRYPT (SI_POSIX && !SI_ANDROID)
  92. -#define SANITIZER_INTERCEPT_CRYPT_R (SI_LINUX && !SI_ANDROID)
  93. #define SANITIZER_INTERCEPT_GETRANDOM \
  94. ((SI_LINUX && __GLIBC_PREREQ(2, 25)) || SI_FREEBSD)
  95. diff --git a/libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.cpp b/libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.cpp
  96. index 5743516c0460..980776fc7d78 100644
  97. --- a/libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.cpp
  98. +++ b/libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.cpp
  99. @@ -142,7 +142,6 @@ typedef struct user_fpregs elf_fpregset_t;
  100. #include <linux/serial.h>
  101. #include <sys/msg.h>
  102. #include <sys/ipc.h>
  103. -#include <crypt.h>
  104. #endif // SANITIZER_LINUX && !SANITIZER_ANDROID
  105. #if SANITIZER_ANDROID
  106. @@ -244,7 +243,6 @@ namespace __sanitizer {
  107. unsigned struct_ustat_sz = SIZEOF_STRUCT_USTAT;
  108. unsigned struct_rlimit64_sz = sizeof(struct rlimit64);
  109. unsigned struct_statvfs64_sz = sizeof(struct statvfs64);
  110. - unsigned struct_crypt_data_sz = sizeof(struct crypt_data);
  111. #endif // SANITIZER_LINUX && !SANITIZER_ANDROID
  112. #if SANITIZER_LINUX && !SANITIZER_ANDROID
  113. diff --git a/libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.h b/libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.h
  114. index 83861105a509..7ad11b943157 100644
  115. --- a/libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.h
  116. +++ b/libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.h
  117. @@ -295,7 +295,6 @@ extern unsigned struct_msqid_ds_sz;
  118. extern unsigned struct_mq_attr_sz;
  119. extern unsigned struct_timex_sz;
  120. extern unsigned struct_statvfs_sz;
  121. -extern unsigned struct_crypt_data_sz;
  122. #endif // SANITIZER_LINUX && !SANITIZER_ANDROID
  123. struct __sanitizer_iovec {
  124. --
  125. 2.43.0