[compiler-rt] [compiler-rt][sanitizer-common] intercept getaddrinfo_a for Linux. (PR #123167)
David CARLIER via llvm-commits
llvm-commits at lists.llvm.org
Thu Jan 16 04:29:43 PST 2025
https://github.com/devnexen updated https://github.com/llvm/llvm-project/pull/123167
>From 5cd7b8bf5c503e02d879770e4774c987da227679 Mon Sep 17 00:00:00 2001
From: David Carlier <devnexen at gmail.com>
Date: Thu, 16 Jan 2025 06:56:14 +0000
Subject: [PATCH] [compiler-rt][sanitizer-common] intercept getaddrinfo_a for
Linux.
---
.../sanitizer_common_interceptors.inc | 53 +++++++++++++++++++
.../sanitizer_platform_interceptors.h | 1 +
.../sanitizer_platform_limits_posix.cpp | 6 +++
.../sanitizer_platform_limits_posix.h | 10 ++++
compiler-rt/test/msan/Linux/getaddrinfo_a.cpp | 32 +++++++++++
5 files changed, 102 insertions(+)
create mode 100644 compiler-rt/test/msan/Linux/getaddrinfo_a.cpp
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc
index 24a8a2d4dc55b4..5ba5f254be47fa 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc
@@ -10263,6 +10263,58 @@ INTERCEPTOR(SSIZE_T, freadlink, int fd, char *buf, SIZE_T bufsiz) {
# define INIT_FREADLINK
#endif
+#if SANITIZER_INTERCEPT_GETADDRINFO_A
+INTERCEPTOR(int, getaddrinfo_a, int mode, struct __sanitizer_gaicb *list,
+ int num, void *sevp) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, getaddrinfo_a, mode, list, num, sevp);
+ if (sevp)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, sevp, struct_sigevent_sz);
+ if (list) {
+ for (int i = 0; i < num; i++) {
+ struct __sanitizer_gaicb *cb = list[i];
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, cb, sizeof(__sanitizer_gaicb));
+ if (cb->ar_name)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, cb->ar_name,
+ internal_strlen(cb->ar_name) + 1);
+ if (cb->ar_service)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, cb->ar_service,
+ internal_strlen(cb->ar_service) + 1);
+ if (cb->ar_request) {
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, cb->ar_request,
+ sizeof(__sanitizer_addrinfo));
+ }
+ }
+ }
+
+ int res = REAL(getaddrinfo_a)(mode, list, num, sevp);
+ if (res == 0 && list) {
+ for (int i = 0; i < num; i++) {
+ struct __sanitizer_addrinfo *result = list[i]->ar_result;
+ if (result) {
+ while (result) {
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result,
+ sizeof(__sanitizer_addrinfo));
+ if (result->ai_addr)
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result->ai_addr,
+ result->ai_addrlen);
+ if (result->ai_canonname)
+ COMMON_INTERCEPTOR_WRITE_RANGE(
+ ctx, result->ai_canonname,
+ internal_strlen(result->ai_canonname) + 1);
+ result = result->ai_next;
+ }
+ }
+ }
+ }
+
+ return res;
+}
+# define INIT_GETADDRINFO_A COMMON_INTERCEPT_FUNCTION(getaddrinfo_a)
+#else
+# define INIT_GETADDRINFO_A
+#endif
+
#include "sanitizer_common_interceptors_netbsd_compat.inc"
namespace __sanitizer {
@@ -10585,6 +10637,7 @@ static void InitializeCommonInterceptors() {
INIT_PREADV2;
INIT_PWRITEV2;
INIT_FREADLINK;
+ INIT_GETADDRINFO_A;
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
index febd233bb1e3c0..4f8bde076f8483 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h
@@ -640,6 +640,7 @@ SANITIZER_WEAK_IMPORT void *aligned_alloc(__sanitizer::usize __alignment,
# define SI_MAC_OS_DEPLOYMENT_MIN_13_00 0
#endif
#define SANITIZER_INTERCEPT_FREADLINK (SI_MAC && SI_MAC_OS_DEPLOYMENT_MIN_13_00)
+#define SANITIZER_GETADDRINFO_A SI_LINUX
// This macro gives a way for downstream users to override the above
// interceptor macros irrespective of the platform they are on. They have
// to do two things:
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.cpp
index ddd67cb43524d4..bed311608daeb8 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.cpp
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.cpp
@@ -1172,6 +1172,12 @@ CHECK_TYPE_SIZE(__kernel_old_gid_t);
CHECK_TYPE_SIZE(__kernel_off_t);
CHECK_TYPE_SIZE(__kernel_loff_t);
CHECK_TYPE_SIZE(__kernel_fd_set);
+
+CHECK_TYPE_SIZE(gaicb);
+CHECK_SIZE_AND_OFFSET(gaicb, ar_name);
+CHECK_SIZE_AND_OFFSET(gaicb, ar_service);
+CHECK_SIZE_AND_OFFSET(gaicb, ar_request);
+CHECK_SIZE_AND_OFFSET(gaicb, ar_result);
#endif
#if !SANITIZER_ANDROID
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h
index 7e62dc0e0523ec..bafbf5d4b5545f 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h
@@ -788,6 +788,16 @@ struct __sanitizer_addrinfo {
struct __sanitizer_addrinfo *ai_next;
};
+# if SANITIZER_LINUX
+struct __sanitizer_gaicb {
+ const char *ar_name;
+ const char *ar_service;
+ const struct __sanitizer_addrinfo *ar_request;
+ struct __sanitizer_addrinfo *ar_result;
+ int __pad[6];
+};
+# endif
+
struct __sanitizer_hostent {
char *h_name;
char **h_aliases;
diff --git a/compiler-rt/test/msan/Linux/getaddrinfo_a.cpp b/compiler-rt/test/msan/Linux/getaddrinfo_a.cpp
new file mode 100644
index 00000000000000..1902057fcdcce8
--- /dev/null
+++ b/compiler-rt/test/msan/Linux/getaddrinfo_a.cpp
@@ -0,0 +1,32 @@
+// RUN: %clangxx_msan -fsanitize-memory-track-origins -O0 %s -o %t && not %run %t >%t.out 2>&1
+// RUN: FileCheck %s < %t.out && FileCheck %s < %t.out
+
+#include <netdb.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+
+int main(void) {
+ const int nm = 4;
+ struct gaicb *list[nm];
+
+ for (auto i = 0; i < nm; i++) {
+ list[i] = (struct gaicb *)malloc(sizeof(struct gaicb));
+ if (i % 2)
+ memset(list[i], 0, sizeof(struct gaicb));
+ list[i]->ar_name = "name";
+ }
+
+ int res = getaddrinfo_a(GAI_WAIT, list, nm, NULL);
+ for (auto i = 0; i < nm; i++) {
+ // CHECK: WARNING: MemorySanitizer: use-of-uninitialized-value
+ // CHECK: {{#0 .* in main.*getaddrinfo_a.cpp:25}}
+ for (auto it = list[i]->ar_result; it; it = it->ai_next) {
+ auto name = it->ai_canonname;
+ }
+
+ free(list[i]);
+ }
+ return 0;
+}
More information about the llvm-commits
mailing list