Skip to content

Commit

Permalink
Move interceptors for libresolv functions to MSan (#119071)
Browse files Browse the repository at this point in the history
The functions are not relevant for most sanitizers and only required for
MSan to see which regions have been written to. This eliminates a link
dependency for all other sanitizers and fixes #59007: while `-lresolv`
had been added for the static runtime in 6dce56b, it wasn't added
to the shared runtimes.

Instead of just moving the interceptors, we adapt them to MSan
conventions:
* We don't skip intercepting when `msan_init_is_running` is true, but
directly call ENSURE_MSAN_INITED() like most other interceptors. It
seems unlikely that these functions are called during initialization.
* We don't unpoison `errno`, because none of the functions is specified
to use it.
  • Loading branch information
aaronpuchert authored Dec 9, 2024
1 parent e55c167 commit f5f9650
Show file tree
Hide file tree
Showing 7 changed files with 107 additions and 152 deletions.
2 changes: 1 addition & 1 deletion clang/lib/Driver/ToolChains/CommonArgs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1410,7 +1410,7 @@ void tools::linkSanitizerRuntimeDeps(const ToolChain &TC,
// libresolv.a, even if exists, is an empty archive to satisfy POSIX -lresolv
// requirement.
if (TC.getTriple().isOSLinux() && !TC.getTriple().isAndroid() &&
!TC.getTriple().isMusl())
!TC.getTriple().isMusl() && TC.getSanitizerArgs(Args).needsMsanRt())
CmdArgs.push_back("-lresolv");
}

Expand Down
39 changes: 20 additions & 19 deletions clang/test/Driver/sanitizer-ld.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
// CHECK-ASAN-LINUX: "-lpthread"
// CHECK-ASAN-LINUX: "-lrt"
// CHECK-ASAN-LINUX: "-ldl"
// CHECK-ASAN-LINUX: "-lresolv"
// CHECK-ASAN-LINUX-NOT: "-lresolv"

// RUN: %clang -fsanitize=address -fno-sanitize-link-runtime -### %s 2>&1 \
// RUN: --target=x86_64-unknown-linux -fuse-ld=ld \
Expand Down Expand Up @@ -143,7 +143,7 @@
// CHECK-ASAN-LINUX-CXX: "-lpthread"
// CHECK-ASAN-LINUX-CXX: "-lrt"
// CHECK-ASAN-LINUX-CXX: "-ldl"
// CHECK-ASAN-LINUX-CXX: "-lresolv"
// CHECK-ASAN-LINUX-CXX-NOT: "-lresolv"

// RUN: %clang -### %s -o /dev/null -fsanitize=address \
// RUN: --target=i386-unknown-linux -fuse-ld=ld -stdlib=platform \
Expand Down Expand Up @@ -292,7 +292,7 @@
// CHECK-TSAN-LINUX-CXX: "-lpthread"
// CHECK-TSAN-LINUX-CXX: "-lrt"
// CHECK-TSAN-LINUX-CXX: "-ldl"
// CHECK-TSAN-LINUX-CXX: "-lresolv"
// CHECK-TSAN-LINUX-CXX-NOT: "-lresolv"

// RUN: %clang -fsanitize=thread -fno-sanitize-link-runtime -### %s 2>&1 \
// RUN: --target=x86_64-unknown-linux -fuse-ld=ld \
Expand Down Expand Up @@ -365,7 +365,7 @@
// CHECK-UBSAN-LINUX-NOT: libclang_rt.ubsan_standalone_cxx
// CHECK-UBSAN-LINUX-NOT: "-lstdc++"
// CHECK-UBSAN-LINUX: "-lpthread"
// CHECK-UBSAN-LINUX: "-lresolv"
// CHECK-UBSAN-LINUX-NOT: "-lresolv"

// RUN: %clang -fsanitize=undefined -fno-sanitize-link-runtime -### %s 2>&1 \
// RUN: --target=x86_64-unknown-linux -fuse-ld=ld \
Expand Down Expand Up @@ -438,7 +438,7 @@
// CHECK-UBSAN-LINUX-CXX: "-lstdc++"
// CHECK-UBSAN-LINUX-CXX-NOT: libclang_rt.asan
// CHECK-UBSAN-LINUX-CXX: "-lpthread"
// CHECK-UBSAN-LINUX-CXX: "-lresolv"
// CHECK-UBSAN-LINUX-CXX-NOT: "-lresolv"

// RUN: %clang -fsanitize=undefined -fsanitize-minimal-runtime -### %s 2>&1 \
// RUN: --target=i386-unknown-linux -fuse-ld=ld \
Expand All @@ -448,7 +448,7 @@
// CHECK-UBSAN-MINIMAL-LINUX: "{{.*}}ld{{(.exe)?}}"
// CHECK-UBSAN-MINIMAL-LINUX: "--whole-archive" "{{.*}}libclang_rt.ubsan_minimal.a" "--no-whole-archive"
// CHECK-UBSAN-MINIMAL-LINUX: "-lpthread"
// CHECK-UBSAN-MINIMAL-LINUX: "-lresolv"
// CHECK-UBSAN-MINIMAL-LINUX-NOT: "-lresolv"

// RUN: %clang -fsanitize=undefined -fsanitize-minimal-runtime -### %s 2>&1 \
// RUN: --target=x86_64-apple-darwin -fuse-ld=ld \
Expand Down Expand Up @@ -485,7 +485,7 @@
// CHECK-ASAN-UBSAN-LINUX-NOT: libclang_rt.ubsan
// CHECK-ASAN-UBSAN-LINUX-NOT: "-lstdc++"
// CHECK-ASAN-UBSAN-LINUX: "-lpthread"
// CHECK-ASAN-UBSAN-LINUX: "-lresolv"
// CHECK-ASAN-UBSAN-LINUX-NOT: "-lresolv"

// RUN: %clangxx -fsanitize=address,undefined -### %s 2>&1 \
// RUN: --target=i386-unknown-linux -fuse-ld=ld -stdlib=platform \
Expand All @@ -498,7 +498,7 @@
// CHECK-ASAN-UBSAN-LINUX-CXX-NOT: libclang_rt.ubsan
// CHECK-ASAN-UBSAN-LINUX-CXX: "-lstdc++"
// CHECK-ASAN-UBSAN-LINUX-CXX: "-lpthread"
// CHECK-ASAN-UBSAN-LINUX-CXX: "-lresolv"
// CHECK-ASAN-UBSAN-LINUX-CXX-NOT: "-lresolv"

// RUN: %clangxx -fsanitize=memory,undefined -### %s 2>&1 \
// RUN: --target=x86_64-unknown-linux -fuse-ld=ld \
Expand Down Expand Up @@ -541,7 +541,7 @@
// CHECK-LSAN-LINUX: libclang_rt.lsan.a"
// CHECK-LSAN-LINUX: "-lpthread"
// CHECK-LSAN-LINUX: "-ldl"
// CHECK-LSAN-LINUX: "-lresolv"
// CHECK-LSAN-LINUX-NOT: "-lresolv"

// RUN: %clang -fsanitize=leak -fno-sanitize-link-runtime -### %s 2>&1 \
// RUN: --target=x86_64-unknown-linux -fuse-ld=ld \
Expand All @@ -564,7 +564,7 @@
// CHECK-LSAN-COV-LINUX-NOT: libclang_rt.ubsan
// CHECK-LSAN-COV-LINUX: "-lpthread"
// CHECK-LSAN-COV-LINUX: "-ldl"
// CHECK-LSAN-COV-LINUX: "-lresolv"
// CHECK-LSAN-COV-LINUX-NOT: "-lresolv"

// RUN: %clang -fsanitize=leak,address -### %s 2>&1 \
// RUN: --target=x86_64-unknown-linux -fuse-ld=ld \
Expand All @@ -586,7 +586,7 @@
// CHECK-ASAN-COV-LINUX-NOT: libclang_rt.ubsan
// CHECK-ASAN-COV-LINUX-NOT: "-lstdc++"
// CHECK-ASAN-COV-LINUX: "-lpthread"
// CHECK-ASAN-COV-LINUX: "-lresolv"
// CHECK-ASAN-COV-LINUX-NOT: "-lresolv"

// RUN: %clang -fsanitize=memory -fsanitize-coverage=func -### %s 2>&1 \
// RUN: --target=x86_64-unknown-linux -fuse-ld=ld \
Expand All @@ -610,7 +610,7 @@
// CHECK-DFSAN-COV-LINUX-NOT: libclang_rt.ubsan
// CHECK-DFSAN-COV-LINUX-NOT: "-lstdc++"
// CHECK-DFSAN-COV-LINUX: "-lpthread"
// CHECK-DFSAN-COV-LINUX: "-lresolv"
// CHECK-DFSAN-COV-LINUX-NOT: "-lresolv"

// RUN: %clang -fsanitize=undefined -fsanitize-coverage=func -### %s 2>&1 \
// RUN: --target=x86_64-unknown-linux -fuse-ld=ld \
Expand All @@ -621,7 +621,7 @@
// CHECK-UBSAN-COV-LINUX: "--whole-archive" "{{.*}}libclang_rt.ubsan_standalone.a" "--no-whole-archive"
// CHECK-UBSAN-COV-LINUX-NOT: "-lstdc++"
// CHECK-UBSAN-COV-LINUX: "-lpthread"
// CHECK-UBSAN-COV-LINUX: "-lresolv"
// CHECK-UBSAN-COV-LINUX-NOT: "-lresolv"

// RUN: %clang -fsanitize-coverage=func -### %s 2>&1 \
// RUN: --target=x86_64-unknown-linux -fuse-ld=ld \
Expand All @@ -632,7 +632,7 @@
// CHECK-COV-LINUX: "--whole-archive" "{{.*}}libclang_rt.ubsan_standalone.a" "--no-whole-archive"
// CHECK-COV-LINUX-NOT: "-lstdc++"
// CHECK-COV-LINUX: "-lpthread"
// CHECK-COV-LINUX: "-lresolv"
// CHECK-COV-LINUX-NOT: "-lresolv"

// RUN: %clang -### %s 2>&1 \
// RUN: --target=x86_64-unknown-linux -fuse-ld=ld -fsanitize=numerical \
Expand All @@ -644,7 +644,8 @@
// CHECK-NSAN-LINUX-NOT: "-lc"
// CHECK-NSAN-LINUX-NOT: libclang_rt.ubsan
// CHECK-NSAN-LINUX: libclang_rt.nsan.a"
// CHECK-NSAN-LINUX: "-lpthread" "-lrt" "-lm" "-ldl" "-lresolv"
// CHECK-NSAN-LINUX: "-lpthread" "-lrt" "-lm" "-ldl"
// CHECK-NSAN-LINUX-NOT: "-lresolv"

// RUN: %clang -### %s 2>&1 --target=x86_64-unknown-linux -fuse-ld=ld -fsanitize=numerical -shared-libsan \
// RUN: -resource-dir=%S/Inputs/resource_dir \
Expand Down Expand Up @@ -757,7 +758,7 @@
// CHECK-SAFESTACK-LINUX: libclang_rt.safestack.a"
// CHECK-SAFESTACK-LINUX: "-lpthread"
// CHECK-SAFESTACK-LINUX: "-ldl"
// CHECK-SAFESTACK-LINUX: "-lresolv"
// CHECK-SAFESTACK-LINUX-NOT: "-lresolv"

// RUN: %clang -fsanitize=shadow-call-stack -### %s 2>&1 \
// RUN: --target=x86_64-unknown-linux -fuse-ld=ld \
Expand Down Expand Up @@ -957,7 +958,7 @@
// CHECK-SCUDO-LINUX-NOT: "-lstdc++"
// CHECK-SCUDO-LINUX: "-lpthread"
// CHECK-SCUDO-LINUX: "-ldl"
// CHECK-SCUDO-LINUX: "-lresolv"
// CHECK-SCUDO-LINUX-NOT: "-lresolv"

// RUN: %clang -### %s -o %t.so -shared 2>&1 \
// RUN: --target=i386-unknown-linux -fuse-ld=ld -fsanitize=scudo -shared-libsan \
Expand Down Expand Up @@ -1018,7 +1019,7 @@
// CHECK-HWASAN-X86-64-LINUX: "-lpthread"
// CHECK-HWASAN-X86-64-LINUX: "-lrt"
// CHECK-HWASAN-X86-64-LINUX: "-ldl"
// CHECK-HWASAN-X86-64-LINUX: "-lresolv"
// CHECK-HWASAN-X86-64-LINUX-NOT: "-lresolv"

// RUN: %clang -### %s 2>&1 \
// RUN: --target=x86_64-unknown-linux -fuse-ld=ld -fsanitize=hwaddress \
Expand Down Expand Up @@ -1067,7 +1068,7 @@
// CHECK-HWASAN-AARCH64-LINUX: "-lpthread"
// CHECK-HWASAN-AARCH64-LINUX: "-lrt"
// CHECK-HWASAN-AARCH64-LINUX: "-ldl"
// CHECK-HWASAN-AARCH64-LINUX: "-lresolv"
// CHECK-HWASAN-AARCH64-LINUX-NOT: "-lresolv"

// RUN: %clang -### %s 2>&1 \
// RUN: --target=aarch64-unknown-linux -fuse-ld=ld -fsanitize=hwaddress \
Expand Down
76 changes: 76 additions & 0 deletions compiler-rt/lib/msan/msan_interceptors.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1358,6 +1358,79 @@ INTERCEPTOR(int, forkpty, int *aparent, char *name, const void *termp,
#define MSAN_MAYBE_INTERCEPT_FORKPTY
#endif

#if SANITIZER_LINUX && !SANITIZER_ANDROID
INTERCEPTOR(int, __b64_ntop, unsigned char const *src, SIZE_T srclength,
char *target, SIZE_T targsize) {
ENSURE_MSAN_INITED();
CHECK_UNPOISONED(src, srclength);
InterceptorScope interceptor_scope;
int res = REAL(__b64_ntop)(src, srclength, target, targsize);
if (res >= 0)
__msan_unpoison(target, res + 1);
return res;
}
INTERCEPTOR(int, __b64_pton, char const *src, char *target, SIZE_T targsize) {
ENSURE_MSAN_INITED();
CHECK_UNPOISONED(src, internal_strlen(src) + 1);
InterceptorScope interceptor_scope;
int res = REAL(__b64_pton)(src, target, targsize);
if (res >= 0)
__msan_unpoison(target, res);
return res;
}
# define MSAN_MAYBE_INTERCEPT___B64_TO \
MSAN_INTERCEPT_FUNC(__b64_ntop); \
COMMON_INTERCEPT_FUNCTION(__b64_pton);
#else
# define MSAN_MAYBE_INTERCEPT___B64_TO
#endif

#if SANITIZER_LINUX && !SANITIZER_ANDROID
# 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) {
ENSURE_MSAN_INITED();
InterceptorScope interceptor_scope;
int res = REAL(DN_COMP_INTERCEPTOR_NAME)(exp_dn, comp_dn, length, dnptrs,
lastdnptr);
if (res >= 0) {
__msan_unpoison(comp_dn, res);
if (dnptrs && lastdnptr) {
unsigned char **p = dnptrs;
for (; p != lastdnptr && *p; ++p);
if (p != lastdnptr)
++p;
__msan_unpoison(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) {
ENSURE_MSAN_INITED();
// TODO: add read check if __dn_comp intercept added
InterceptorScope interceptor_scope;
int res = REAL(DN_EXPAND_INTERCEPTOR_NAME)(base, end, src, dest, space);
if (res >= 0)
__msan_unpoison(dest, internal_strlen(dest) + 1);
return res;
}
# define MSAN_MAYBE_INTERCEPT_DN_COMP_EXPAND \
MSAN_INTERCEPT_FUNC(DN_COMP_INTERCEPTOR_NAME); \
MSAN_INTERCEPT_FUNC(DN_EXPAND_INTERCEPTOR_NAME);
#else
# define MSAN_MAYBE_INTERCEPT_DN_COMP_EXPAND
#endif

struct MSanInterceptorContext {
bool in_interceptor_scope;
};
Expand Down Expand Up @@ -1916,6 +1989,9 @@ void InitializeInterceptors() {
MSAN_MAYBE_INTERCEPT_OPENPTY;
MSAN_MAYBE_INTERCEPT_FORKPTY;

MSAN_MAYBE_INTERCEPT___B64_TO;
MSAN_MAYBE_INTERCEPT_DN_COMP_EXPAND;

inited = 1;
}
} // namespace __msan
78 changes: 0 additions & 78 deletions compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc
Original file line number Diff line number Diff line change
Expand Up @@ -2538,82 +2538,6 @@ INTERCEPTOR(int, glob64, const char *pattern, int flags,
#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, res + 1);
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_RANGE(ctx, src, internal_strlen(src) + 1);
int res = REAL(__b64_pton)(src, target, targsize);
if (res >= 0)
COMMON_INTERCEPTOR_WRITE_RANGE(ctx, target, res);
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_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) {
void *ctx;
COMMON_INTERCEPTOR_ENTER(ctx, DN_EXPAND_INTERCEPTOR_NAME, base, end, src,
dest, space);
// TODO: add read check if __dn_comp intercept added
int res = REAL(DN_EXPAND_INTERCEPTOR_NAME)(base, end, src, dest, space);
if (res >= 0)
COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, internal_strlen(dest) + 1);
return res;
}
# define INIT_DN_COMP_EXPAND \
COMMON_INTERCEPT_FUNCTION(DN_COMP_INTERCEPTOR_NAME); \
COMMON_INTERCEPT_FUNCTION(DN_EXPAND_INTERCEPTOR_NAME);
#else // SANITIZER_INTERCEPT_DN_COMP_EXPAND
# define INIT_DN_COMP_EXPAND
#endif // SANITIZER_INTERCEPT_DN_COMP_EXPAND

#if SANITIZER_INTERCEPT_POSIX_SPAWN

template <class RealSpawnPtr>
Expand Down Expand Up @@ -10346,8 +10270,6 @@ static void InitializeCommonInterceptors() {
INIT_TIMESPEC_GET;
INIT_GLOB;
INIT_GLOB64;
INIT___B64_TO;
INIT_DN_COMP_EXPAND;
INIT_POSIX_SPAWN;
INIT_WAIT;
INIT_WAIT4;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -266,8 +266,6 @@ SANITIZER_WEAK_IMPORT void *aligned_alloc(__sanitizer::usize __alignment,
#define SANITIZER_INTERCEPT_TIMESPEC_GET SI_LINUX
#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_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
Expand Down
Loading

0 comments on commit f5f9650

Please sign in to comment.