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 @@ -2492,6 +2492,36 @@ #define INIT_GLOB64 #endif // SANITIZER_INTERCEPT_GLOB64 +#if SANITIZER_INTERCEPT___B64_TO +INTERCEPTOR(int, __b64_ntop, unsigned char const *src, SIZE_T srclength, + char *target, SIZE_T targsize) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, __b64_ntop, src, srclength, target, targsize); + COMMON_INTERCEPTOR_READ_RANGE(ctx, src, srclength); + int res = REAL(__b64_ntop)(src, srclength, target, targsize); + if (res >= 0) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, target, + (SIZE_T)res < targsize ? res + 1 : targsize); + return res; +} +INTERCEPTOR(int, __b64_pton, char const *src, char *target, SIZE_T targsize) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, __b64_pton, src, target, targsize); + COMMON_INTERCEPTOR_READ_STRING(ctx, src, 0); + int res = REAL(__b64_pton)(src, target, targsize); + if (res >= 0) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, target, + (SIZE_T)res < targsize ? res + 1 : targsize); + return res; +} +# define INIT___B64_TO \ + COMMON_INTERCEPT_FUNCTION(__b64_ntop); \ + COMMON_INTERCEPT_FUNCTION(__b64_pton); +#else // SANITIZER_INTERCEPT___B64_TO +#define INIT___B64_TO +#endif // SANITIZER_INTERCEPT___B64_TO + + #if SANITIZER_INTERCEPT_POSIX_SPAWN template @@ -10392,6 +10422,7 @@ INIT_TIME; INIT_GLOB; INIT_GLOB64; + INIT___B64_TO; INIT_POSIX_SPAWN; INIT_WAIT; INIT_WAIT4; 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 @@ -235,6 +235,7 @@ #define SANITIZER_INTERCEPT_TIME SI_POSIX #define SANITIZER_INTERCEPT_GLOB (SI_GLIBC || SI_SOLARIS) #define SANITIZER_INTERCEPT_GLOB64 SI_GLIBC +#define SANITIZER_INTERCEPT___B64_TO SI_LINUX #define SANITIZER_INTERCEPT_POSIX_SPAWN SI_POSIX #define SANITIZER_INTERCEPT_WAIT SI_POSIX #define SANITIZER_INTERCEPT_INET SI_POSIX diff --git a/compiler-rt/test/msan/Linux/b64.cpp b/compiler-rt/test/msan/Linux/b64.cpp new file mode 100644 --- /dev/null +++ b/compiler-rt/test/msan/Linux/b64.cpp @@ -0,0 +1,25 @@ +// RUN: %clangxx_msan -O0 %s -o %t -lresolv && %run %t %p 2>&1 | FileCheck %s + +//#include +#include +#include +#include +#include + +int main(int argc, char *argv[]) { + const char *src = "base64 test data"; + size_t src_len = strlen(src); + size_t dst_len = ((src_len + 2) / 3) * 4 + 1; + char *dst = reinterpret_cast(malloc(dst_len)); + int res = b64_ntop(reinterpret_cast(src), src_len, dst, + dst_len); + printf("%lu - %s\n", strlen(dst), dst); + // CHECK-NOT: Uninitialized bytes + // CHECK-NOT: WARNING: MemorySanitizer: use-of-uninitialized-value + unsigned char *target = reinterpret_cast(malloc(dst_len)); + res = b64_pton(dst, target, dst_len); + printf("%lu - %s\n", strlen(reinterpret_cast(target)), target); + // CHECK-NOT: Uninitialized bytes + // CHECK-NOT: WARNING: MemorySanitizer: use-of-uninitialized-value + return 0; +}