-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[compiler-rt][sanitizer-common] intercept getaddrinfo_a for Linux. #123167
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
You can test this locally with the following command:git-clang-format --diff 1797fb6b233c548817008b9c39c6af06d12cae99 5cd7b8bf5c503e02d879770e4774c987da227679 --extensions h,cpp,inc -- compiler-rt/test/msan/Linux/getaddrinfo_a.cpp compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.cpp compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h View the diff from clang-format here.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 bed311608d..a7627d8748 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.cpp
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.cpp
@@ -1178,9 +1178,9 @@ 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
+# endif
-#if !SANITIZER_ANDROID
+# if !SANITIZER_ANDROID
CHECK_TYPE_SIZE(wordexp_t);
CHECK_SIZE_AND_OFFSET(wordexp_t, we_wordc);
CHECK_SIZE_AND_OFFSET(wordexp_t, we_wordv);
|
fbf4bf1
to
44f877a
Compare
c7c5362
to
5cd7b8b
Compare
@llvm/pr-subscribers-compiler-rt-sanitizer Author: David CARLIER (devnexen) ChangesFull diff: https://github.com/llvm/llvm-project/pull/123167.diff 5 Files Affected:
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;
+}
|
} | ||
|
||
int res = REAL(getaddrinfo_a)(mode, list, num, sevp); | ||
if (res == 0 && list) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it's probably incorrect for NOWAIT?
implementation can memcpy from internal buffers after we call WRITE_RANGE
I guess we need to replace sevp with own handler, and then WRITE_RANGE before calling the real one.
No description provided.