diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc --- a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc +++ b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc @@ -9573,6 +9573,38 @@ #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)(key, salt); + if (res != nullptr) + 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 + static void InitializeCommonInterceptors() { #if SI_POSIX static u64 metadata_mem[sizeof(MetadataHashMap) / sizeof(u64) + 1]; @@ -9871,6 +9903,8 @@ INIT_GETUSERSHELL; INIT_SL_INIT; INIT_GETRANDOM; + INIT_CRYPT; + INIT_CRYPT_R; INIT___PRINTF_CHK; } diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h b/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h --- a/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h @@ -565,6 +565,8 @@ #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 #define SANITIZER_INTERCEPT___CXA_ATEXIT SI_NETBSD diff --git a/compiler-rt/test/msan/Linux/crypt_r.cpp b/compiler-rt/test/msan/Linux/crypt_r.cpp new file mode 100644 --- /dev/null +++ b/compiler-rt/test/msan/Linux/crypt_r.cpp @@ -0,0 +1,17 @@ +// RUN: %clangxx_msan -O0 -g %s -lcrypt -o %t && %run %t + +#include +#include +#include +#include + +#include + +int +main (int argc, char** argv) +{ + crypt_data cd; + cd.initialized = 0; + char *p = crypt_r("abcdef", "xz", &cd); + assert(__msan_test_shadow(p, strlen(p) + 1) == -1); +} diff --git a/compiler-rt/test/msan/crypt.cpp b/compiler-rt/test/msan/crypt.cpp new file mode 100644 --- /dev/null +++ b/compiler-rt/test/msan/crypt.cpp @@ -0,0 +1,14 @@ +// RUN: %clangxx_msan -O0 -g %s -lcrypt -o %t && %run %t + +#include +#include +#include + +#include + +int +main (int argc, char** argv) +{ + char *p = crypt("abcdef", "xz"); + assert(__msan_test_shadow(p, strlen(p) + 1) == -1); +}