Skip to content

[compiler-rt][rtsan] intercept getpeername/recvmmsg/sendmmsg #123484

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

Merged
merged 1 commit into from
Jan 20, 2025

Conversation

devnexen
Copy link
Member

No description provided.

@llvmbot
Copy link
Member

llvmbot commented Jan 18, 2025

@llvm/pr-subscribers-compiler-rt-sanitizer

Author: David CARLIER (devnexen)

Changes

Full diff: https://github.com/llvm/llvm-project/pull/123484.diff

2 Files Affected:

  • (modified) compiler-rt/lib/rtsan/rtsan_interceptors_posix.cpp (+36)
  • (modified) compiler-rt/lib/rtsan/tests/rtsan_test_interceptors_posix.cpp (+28)
diff --git a/compiler-rt/lib/rtsan/rtsan_interceptors_posix.cpp b/compiler-rt/lib/rtsan/rtsan_interceptors_posix.cpp
index 7ab54c24a002f3..76e29a591c9934 100644
--- a/compiler-rt/lib/rtsan/rtsan_interceptors_posix.cpp
+++ b/compiler-rt/lib/rtsan/rtsan_interceptors_posix.cpp
@@ -840,6 +840,17 @@ INTERCEPTOR(int, getsockname, int socket, struct sockaddr *sa,
 #define RTSAN_MAYBE_INTERCEPT_GETSOCKNAME
 #endif
 
+#if SANITIZER_INTERCEPT_GETPEERNAME
+INTERCEPTOR(int, getpeername, int socket, struct sockaddr *sa,
+            socklen_t *salen) {
+  __rtsan_notify_intercepted_call("getpeername");
+  return REAL(getpeername)(socket, sa, salen);
+}
+#define RTSAN_MAYBE_INTERCEPT_GETPEERNAME INTERCEPT_FUNCTION(getpeername)
+#else
+#define RTSAN_MAYBE_INTERCEPT_GETPEERNAME
+#endif
+
 INTERCEPTOR(int, bind, int socket, const struct sockaddr *address,
             socklen_t address_len) {
   __rtsan_notify_intercepted_call("bind");
@@ -879,6 +890,17 @@ INTERCEPTOR(ssize_t, sendmsg, int socket, const struct msghdr *message,
   return REAL(sendmsg)(socket, message, flags);
 }
 
+#if SANITIZER_INTERCEPT_SENDMMSG
+INTERCEPTOR(int, sendmmsg, int socket, struct mmsghdr *message,
+            unsigned int len, int flags) {
+  __rtsan_notify_intercepted_call("sendmmsg");
+  return REAL(sendmmsg)(socket, message, len, flags);
+}
+#define RTSAN_MAYBE_INTERCEPT_SENDMMSG INTERCEPT_FUNCTION(sendmmsg)
+#else
+#define RTSAN_MAYBE_INTERCEPT_SENDMMSG
+#endif
+
 INTERCEPTOR(ssize_t, sendto, int socket, const void *buffer, size_t length,
             int flags, const struct sockaddr *dest_addr, socklen_t dest_len) {
   __rtsan_notify_intercepted_call("sendto");
@@ -901,6 +923,17 @@ INTERCEPTOR(ssize_t, recvmsg, int socket, struct msghdr *message, int flags) {
   return REAL(recvmsg)(socket, message, flags);
 }
 
+#if SANITIZER_INTERCEPT_RECVMMSG
+INTERCEPTOR(int, recvmmsg, int socket, struct mmsghdr *message,
+            unsigned int len, int flags, struct timespec *timeout) {
+  __rtsan_notify_intercepted_call("recvmmsg");
+  return REAL(recvmmsg)(socket, message, len, flags, timeout);
+}
+#define RTSAN_MAYBE_INTERCEPT_RECVMMSG INTERCEPT_FUNCTION(recvmmsg)
+#else
+#define RTSAN_MAYBE_INTERCEPT_RECVMMSG
+#endif
+
 INTERCEPTOR(int, shutdown, int socket, int how) {
   __rtsan_notify_intercepted_call("shutdown");
   return REAL(shutdown)(socket, how);
@@ -1194,13 +1227,16 @@ void __rtsan::InitializeInterceptors() {
   INTERCEPT_FUNCTION(recv);
   INTERCEPT_FUNCTION(recvfrom);
   INTERCEPT_FUNCTION(recvmsg);
+  RTSAN_MAYBE_INTERCEPT_RECVMMSG;
   INTERCEPT_FUNCTION(send);
   INTERCEPT_FUNCTION(sendmsg);
+  RTSAN_MAYBE_INTERCEPT_SENDMMSG;
   INTERCEPT_FUNCTION(sendto);
   INTERCEPT_FUNCTION(shutdown);
   INTERCEPT_FUNCTION(socket);
   RTSAN_MAYBE_INTERCEPT_ACCEPT4;
   RTSAN_MAYBE_INTERCEPT_GETSOCKNAME;
+  RTSAN_MAYBE_INTERCEPT_GETPEERNAME;
 
   RTSAN_MAYBE_INTERCEPT_SELECT;
   INTERCEPT_FUNCTION(pselect);
diff --git a/compiler-rt/lib/rtsan/tests/rtsan_test_interceptors_posix.cpp b/compiler-rt/lib/rtsan/tests/rtsan_test_interceptors_posix.cpp
index 0e03b19e80b6c5..0ce1844f05eab0 100644
--- a/compiler-rt/lib/rtsan/tests/rtsan_test_interceptors_posix.cpp
+++ b/compiler-rt/lib/rtsan/tests/rtsan_test_interceptors_posix.cpp
@@ -1118,6 +1118,15 @@ TEST(TestRtsanInterceptors, SendmsgToASocketDiesWhenRealtime) {
   ExpectNonRealtimeSurvival(Func);
 }
 
+#if SANITIZER_INTERCEPT_SENDMMSG
+TEST(TestRtsanInterceptors, SendmmsgOnASocketDiesWhenRealtime) {
+  mmsghdr msg{};
+  auto Func = [&]() { sendmmsg(0, &msg, 0, 0); };
+  ExpectRealtimeDeath(Func, "sendmmsg");
+  ExpectNonRealtimeSurvival(Func);
+}
+#endif
+
 TEST(TestRtsanInterceptors, SendtoToASocketDiesWhenRealtime) {
   sockaddr addr{};
   socklen_t len{};
@@ -1147,6 +1156,15 @@ TEST(TestRtsanInterceptors, RecvmsgOnASocketDiesWhenRealtime) {
   ExpectNonRealtimeSurvival(Func);
 }
 
+#if SANITIZER_INTERCEPT_RECVMMSG
+TEST(TestRtsanInterceptors, RecvmmsgOnASocketDiesWhenRealtime) {
+  mmsghdr msg{};
+  auto Func = [&]() { recvmmsg(0, &msg, 0, 0, nullptr); };
+  ExpectRealtimeDeath(Func, "recvmmsg");
+  ExpectNonRealtimeSurvival(Func);
+}
+#endif
+
 TEST(TestRtsanInterceptors, ShutdownOnASocketDiesWhenRealtime) {
   auto Func = [&]() { shutdown(0, 0); };
   ExpectRealtimeDeath(Func, "shutdown");
@@ -1163,6 +1181,16 @@ TEST(TestRtsanInterceptors, GetsocknameOnASocketDiesWhenRealtime) {
 }
 #endif
 
+#if SANITIZER_INTERCEPT_GETPEERNAME
+TEST(TestRtsanInterceptors, GetpeernameOnASocketDiesWhenRealtime) {
+  sockaddr addr{};
+  socklen_t len{};
+  auto Func = [&]() { getpeername(0, &addr, &len); };
+  ExpectRealtimeDeath(Func, "getpeername");
+  ExpectNonRealtimeSurvival(Func);
+}
+#endif
+
 /*
     I/O Multiplexing
 */

@devnexen devnexen merged commit 18d5d84 into llvm:main Jan 20, 2025
10 checks passed
@Zentrik
Copy link
Contributor

Zentrik commented Jan 20, 2025

It seems prior to glibc 2.21 (specifically bminor/glibc@20e5a5f), recvmmsg had a slightly different declaration where the timespec* was const.

[16:24:33] In file included from /workspace/srcdir/llvm-project/compiler-rt/lib/rtsan/rtsan_interceptors_posix.cpp:16:
[16:24:33] /workspace/srcdir/llvm-project/compiler-rt/lib/rtsan/rtsan_interceptors_posix.cpp:930:18: error: conflicting declaration of C function ‘int recvmmsg(int, mmsghdr*, unsigned int, int, timespec*)’
[16:24:33]   930 | INTERCEPTOR(int, recvmmsg, int socket, struct mmsghdr *message,
[16:24:33]       |                  ^~~~~~~~
[16:24:33] /workspace/srcdir/llvm-project/compiler-rt/lib/rtsan/../interception/interception.h:206:26: note: in definition of macro ‘DECLARE_WRAPPER’
[16:24:33]   206 |      extern "C" ret_type func(__VA_ARGS__);                                    \
[16:24:33]       |                          ^~~~
[16:24:33] /workspace/srcdir/llvm-project/compiler-rt/lib/rtsan/rtsan_interceptors_posix.cpp:930:1: note: in expansion of macro ‘INTERCEPTOR’
[16:24:33]   930 | INTERCEPTOR(int, recvmmsg, int socket, struct mmsghdr *message,
[16:24:33]       | ^~~~~~~~~~~
[16:24:33] In file included from /workspace/srcdir/llvm-project/compiler-rt/lib/rtsan/rtsan_interceptors_posix.cpp:50:
[16:24:33] /opt/x86_64-linux-gnu/x86_64-linux-gnu/sys-root/usr/include/sys/socket.h:211:12: note: previous declaration ‘int recvmmsg(int, mmsghdr*, unsigned int, int, const timespec*)’
[16:24:33]   211 | extern int recvmmsg (int __fd, struct mmsghdr *__vmessages,
[16:24:33]       |            ^~~~~~~~

@devnexen
Copy link
Member Author

Lovely ! Looking into it.

devnexen added a commit to devnexen/llvm-project that referenced this pull request Jan 20, 2025
linux/glibc prior to 2.21 had a different signature for recvmmsg.
@PiJoules
Copy link
Contributor

This is still breaking our builders at https://logs.chromium.org/logs/fuchsia/buildbucket/cr-buildbucket/8725110728072470801/+/u/clang/build/stdout?format=raw:

FAILED: compiler-rt/lib/rtsan/CMakeFiles/RTRtsan.aarch64.dir/rtsan_interceptors_posix.cpp.o 
/b/s/w/ir/x/w/llvm_build/./bin/clang++ --target=aarch64-unknown-linux-gnu --sysroot=/b/s/w/ir/x/w/cipd/linux -D_DEBUG -D_GLIBCXX_ASSERTIONS -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -I/b/s/w/ir/x/w/llvm-llvm-project/compiler-rt/lib/rtsan/.. --target=aarch64-unknown-linux-gnu -fPIC -fno-semantic-interposition -fvisibility-inlines-hidden -Werror=date-time -Werror=unguarded-availability-new -Wall -Wextra -Wno-unused-parameter -Wwrite-strings -Wcast-qual -Wmissing-field-initializers -Wimplicit-fallthrough -Wcovered-switch-default -Wno-noexcept-type -Wnon-virtual-dtor -Wdelete-non-virtual-dtor -Wsuggest-override -Wstring-conversion -Wmisleading-indentation -Wctad-maybe-unsupported -fdiagnostics-color -ffunction-sections -fdata-sections -ffile-prefix-map=/b/s/w/ir/x/w/llvm_build/runtimes/runtimes-aarch64-unknown-linux-gnu-bins=../../../llvm-llvm-project -ffile-prefix-map=/b/s/w/ir/x/w/llvm-llvm-project/= -no-canonical-prefixes -Wall -Wno-unused-parameter -O2 -g -DNDEBUG -std=c++17 -fPIC -fno-builtin -fno-exceptions -fomit-frame-pointer -funwind-tables -fno-stack-protector -fno-sanitize=safe-stack -fvisibility=hidden -fno-lto -Wthread-safety -Wthread-safety-reference -Wthread-safety-beta -O3 -gline-tables-only -Wno-gnu -Wno-variadic-macros -Wno-c99-extensions -ftrivial-auto-var-init=pattern -nostdinc++ -isystem/b/s/w/ir/x/w/llvm_build/include/aarch64-unknown-linux-gnu/c++/v1 -isystem/b/s/w/ir/x/w/llvm_build/include/c++/v1 -isystem/b/s/w/ir/x/w/llvm-llvm-project/libcxxabi/include -DSANITIZER_COMMON_NO_REDEFINE_BUILTINS -fno-rtti -MD -MT compiler-rt/lib/rtsan/CMakeFiles/RTRtsan.aarch64.dir/rtsan_interceptors_posix.cpp.o -MF compiler-rt/lib/rtsan/CMakeFiles/RTRtsan.aarch64.dir/rtsan_interceptors_posix.cpp.o.d -o compiler-rt/lib/rtsan/CMakeFiles/RTRtsan.aarch64.dir/rtsan_interceptors_posix.cpp.o -c /b/s/w/ir/x/w/llvm-llvm-project/compiler-rt/lib/rtsan/rtsan_interceptors_posix.cpp
/b/s/w/ir/x/w/llvm-llvm-project/compiler-rt/lib/rtsan/rtsan_interceptors_posix.cpp:930:18: error: conflicting types for 'recvmmsg'
  930 | INTERCEPTOR(int, recvmmsg, int socket, struct mmsghdr *message,
      |                  ^
/b/s/w/ir/x/w/cipd/linux/usr/include/aarch64-linux-gnu/sys/socket.h:210:12: note: previous declaration is here
  210 | extern int recvmmsg (int __fd, struct mmsghdr *__vmessages,
      |            ^
1 error generated.

It looks like it's also due to a different signature. Could you send out a fix or revert? Thanks.

@devnexen
Copy link
Member Author

devnexen commented Jan 21, 2025

The fix is in review still. Going to commit soon sorry for the disturbance.

devnexen added a commit to devnexen/llvm-project that referenced this pull request Jan 21, 2025
linux/glibc prior to 2.21 had a different signature for recvmmsg.

Fix llvm#123484
devnexen added a commit that referenced this pull request Jan 21, 2025
…123664)

linux/glibc prior to 2.21 had a different signature for recvmmsg.

Fix #123484
kongy added a commit that referenced this pull request Jan 22, 2025
…MUSL (#123907)

MUSL have different signatures for sendmmsg and recvmmsg.

This fixes build breakage from #123484.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants