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 @@ -2518,13 +2518,31 @@ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, target, res); return res; } -# define INIT___B64_TO \ +#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___DN_EXPAND + INTERCEPTOR(int, __dn_expand, unsigned char const *base, + unsigned char const *end, unsigned char const *src, char *dest, + int space) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, __dn_expand, base, end, src, dest, space); + // TODO: add read check if __dn_comp intercept added + int res = REAL(__dn_expand)(base, end, src, dest, space); + if (res >= 0) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, res + 1); + return res; +} +#define INIT___DN_EXPAND \ + COMMON_INTERCEPT_FUNCTION(__dn_expand); +#else // SANITIZER_INTERCEPT___DN_EXPAND +#define INIT___DN_EXPAND +#endif // SANITIZER_INTERCEPT___DN_EXPAND + #if SANITIZER_INTERCEPT_POSIX_SPAWN @@ -10427,6 +10445,7 @@ INIT_GLOB; INIT_GLOB64; INIT___B64_TO; + INIT___DN_EXPAND; 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 @@ -236,6 +236,7 @@ #define SANITIZER_INTERCEPT_GLOB (SI_GLIBC || SI_SOLARIS) #define SANITIZER_INTERCEPT_GLOB64 SI_GLIBC #define SANITIZER_INTERCEPT___B64_TO SI_LINUX_NOT_ANDROID +#define SANITIZER_INTERCEPT___DN_EXPAND SI_LINUX_NOT_ANDROID #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/dn_expand.cpp b/compiler-rt/test/msan/Linux/dn_expand.cpp new file mode 100644 --- /dev/null +++ b/compiler-rt/test/msan/Linux/dn_expand.cpp @@ -0,0 +1,42 @@ +// RUN: %clangxx_msan -O0 %s -o %t -lresolv && %run %t + +#include +#include +#include + +#include + +void testWrite() { + char unsigned input[] = {0xff, 0xc5, 0xf7, 0xff, 0x00, 0x00, 0xff, 0x0a, 0x00, + 0x00, 0x00, 0x01, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, + 0x10, 0x01, 0x05, 0x00, 0x01, 0x0a, 0x67, 0x6f, 0x6f, + 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x00}; + char output[1024]; + + int res = dn_expand(input, input + sizeof(input), input + 23, output, + sizeof(output)); + + assert(res >= 0); + __msan_check_mem_is_initialized(output, res); +} + +void testWriteZeroLength() { + char unsigned input[] = { + 0xff, 0xc5, 0xf7, 0xff, 0x00, 0x00, 0xff, 0x0a, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x10, 0x01, 0x05, 0x00, 0x01, 0x00, + }; + char output[1024]; + + int res = dn_expand(input, input + sizeof(input), input + 23, output, + sizeof(output)); + + assert(res >= 0); + __msan_check_mem_is_initialized(output, res); +} + +int main(int iArgc, const char *szArgv[]) { + testWrite(); + testWriteZeroLength(); + + return 0; +} diff --git a/compiler-rt/test/sanitizer_common/TestCases/Linux/dn_expand.cpp b/compiler-rt/test/sanitizer_common/TestCases/Linux/dn_expand.cpp new file mode 100644 --- /dev/null +++ b/compiler-rt/test/sanitizer_common/TestCases/Linux/dn_expand.cpp @@ -0,0 +1,42 @@ +// RUN: %clangxx %s -o %t -lresolv && %run %t %p + +#include +#include +#include + +#include + +void testWrite() { + char unsigned input[] = {0xff, 0xc5, 0xf7, 0xff, 0x00, 0x00, 0xff, 0x0a, 0x00, + 0x00, 0x00, 0x01, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, + 0x10, 0x01, 0x05, 0x00, 0x01, 0x0a, 0x67, 0x6f, 0x6f, + 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x00}; + char output[1024]; + + int res = dn_expand(input, input + sizeof(input), input + 23, output, + sizeof(output)); + + assert(res == 12); + assert(strcmp(output, "google\\.com") == 0); +} + +void testWriteZeroLength() { + char unsigned input[] = { + 0xff, 0xc5, 0xf7, 0xff, 0x00, 0x00, 0xff, 0x0a, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x10, 0x01, 0x05, 0x00, 0x01, 0x00, + }; + char output[1024]; + + int res = dn_expand(input, input + sizeof(input), input + 23, output, + sizeof(output)); + + assert(res == 1); + assert(strcmp(output, "") == 0); +} + +int main(int iArgc, const char *szArgv[]) { + testWrite(); + testWriteZeroLength(); + + return 0; +}