diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc index 9af296b1853a9f..cd9235e503b13c 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc +++ b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc @@ -2530,13 +2530,36 @@ INTERCEPTOR(int, __b64_pton, char const *src, char *target, SIZE_T targsize) { #define INIT___B64_TO #endif // SANITIZER_INTERCEPT___B64_TO -#if SANITIZER_INTERCEPT___DN_EXPAND +#if SANITIZER_INTERCEPT_DN_COMP_EXPAND # if __GLIBC_PREREQ(2, 34) // Changed with https://sourceware.org/git/?p=glibc.git;h=640bbdf +# define DN_COMP_INTERCEPTOR_NAME dn_comp # define DN_EXPAND_INTERCEPTOR_NAME dn_expand # else +# define DN_COMP_INTERCEPTOR_NAME __dn_comp # define DN_EXPAND_INTERCEPTOR_NAME __dn_expand # endif +INTERCEPTOR(int, DN_COMP_INTERCEPTOR_NAME, unsigned char *exp_dn, + unsigned char *comp_dn, int length, unsigned char **dnptrs, + unsigned char **lastdnptr) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, DN_COMP_INTERCEPTOR_NAME, exp_dn, comp_dn, + length, dnptrs, lastdnptr); + int res = REAL(DN_COMP_INTERCEPTOR_NAME)(exp_dn, comp_dn, length, dnptrs, + lastdnptr); + if (res >= 0) { + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, comp_dn, res); + if (dnptrs && lastdnptr) { + unsigned char **p = dnptrs; + for (; p != lastdnptr && *p; ++p) + ; + if (p != lastdnptr) + ++p; + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dnptrs, (p - dnptrs) * sizeof(*p)); + } + } + return res; +} INTERCEPTOR(int, DN_EXPAND_INTERCEPTOR_NAME, unsigned char const *base, unsigned char const *end, unsigned char const *src, char *dest, int space) { @@ -2549,11 +2572,12 @@ INTERCEPTOR(int, DN_EXPAND_INTERCEPTOR_NAME, unsigned char const *base, COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, internal_strlen(dest) + 1); return res; } -# define INIT___DN_EXPAND \ +# define INIT_DN_COMP_EXPAND \ + COMMON_INTERCEPT_FUNCTION(DN_COMP_INTERCEPTOR_NAME); \ COMMON_INTERCEPT_FUNCTION(DN_EXPAND_INTERCEPTOR_NAME); -#else // SANITIZER_INTERCEPT___DN_EXPAND -# define INIT___DN_EXPAND -#endif // SANITIZER_INTERCEPT___DN_EXPAND +#else // SANITIZER_INTERCEPT_DN_COMP_EXPAND +# define INIT_DN_COMP_EXPAND +#endif // SANITIZER_INTERCEPT_DN_COMP_EXPAND #if SANITIZER_INTERCEPT_POSIX_SPAWN @@ -10513,7 +10537,7 @@ static void InitializeCommonInterceptors() { INIT_GLOB; INIT_GLOB64; INIT___B64_TO; - INIT___DN_EXPAND; + INIT_DN_COMP_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 index ffa7e272b7e019..6e3081ec1fcca6 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h @@ -236,7 +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_DN_COMP_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/sanitizer_common/TestCases/Linux/dn_expand.cpp b/compiler-rt/test/sanitizer_common/TestCases/Linux/dn_expand.cpp index 2b22f80bdab4d3..8fdfa7a6cc1a4c 100644 --- a/compiler-rt/test/sanitizer_common/TestCases/Linux/dn_expand.cpp +++ b/compiler-rt/test/sanitizer_common/TestCases/Linux/dn_expand.cpp @@ -49,11 +49,17 @@ void testComp() { char unsigned *n1 = mb; int res = dn_comp("llvm.org", mb, me - mb, pb, pe); assert(res == 10); + check_mem_is_good(mb, res); + // pb is [msg, llvm.org, nullptr] + check_mem_is_good(pb, sizeof(*pb) * 3); mb += res; char unsigned *n2 = mb; res = dn_comp("lab.llvm.org", mb, me - mb, pb, pe); assert(res == 6); + check_mem_is_good(mb, res); + // pb is [msg, llvm.org, lab.llvm.org, nullptr] + check_mem_is_good(pb, sizeof(*pb) * 4); mb += res; {