[compiler-rt] 3a8b28f - [rtsan] Add ioctl interceptor (#117569)
via llvm-commits
llvm-commits at lists.llvm.org
Tue Nov 26 15:17:08 PST 2024
Author: Chris Apple
Date: 2024-11-26T15:17:04-08:00
New Revision: 3a8b28f69837f8502c7bce798509f8dadb314dcc
URL: https://github.com/llvm/llvm-project/commit/3a8b28f69837f8502c7bce798509f8dadb314dcc
DIFF: https://github.com/llvm/llvm-project/commit/3a8b28f69837f8502c7bce798509f8dadb314dcc.diff
LOG: [rtsan] Add ioctl interceptor (#117569)
Added:
Modified:
compiler-rt/lib/rtsan/rtsan_interceptors_posix.cpp
compiler-rt/lib/rtsan/tests/rtsan_test_interceptors_posix.cpp
Removed:
################################################################################
diff --git a/compiler-rt/lib/rtsan/rtsan_interceptors_posix.cpp b/compiler-rt/lib/rtsan/rtsan_interceptors_posix.cpp
index 91d023e858ba3b..5debf13ab9815c 100644
--- a/compiler-rt/lib/rtsan/rtsan_interceptors_posix.cpp
+++ b/compiler-rt/lib/rtsan/rtsan_interceptors_posix.cpp
@@ -190,6 +190,23 @@ INTERCEPTOR(int, fcntl, int filedes, int cmd, ...) {
return REAL(fcntl)(filedes, cmd, arg);
}
+INTERCEPTOR(int, ioctl, int filedes, unsigned long request, ...) {
+ __rtsan_notify_intercepted_call("ioctl");
+
+ // See fcntl for discussion on why we use intptr_t
+ // And why we read from va_args on all request types
+ using arg_type = intptr_t;
+ static_assert(sizeof(arg_type) >= sizeof(struct ifreq *));
+ static_assert(sizeof(arg_type) >= sizeof(int));
+
+ va_list args;
+ va_start(args, request);
+ arg_type arg = va_arg(args, arg_type);
+ va_end(args);
+
+ return REAL(ioctl)(filedes, request, arg);
+}
+
#if SANITIZER_INTERCEPT_FCNTL64
INTERCEPTOR(int, fcntl64, int filedes, int cmd, ...) {
__rtsan_notify_intercepted_call("fcntl64");
@@ -801,6 +818,7 @@ void __rtsan::InitializeInterceptors() {
RTSAN_MAYBE_INTERCEPT_LSEEK64;
INTERCEPT_FUNCTION(dup);
INTERCEPT_FUNCTION(dup2);
+ INTERCEPT_FUNCTION(ioctl);
#if SANITIZER_APPLE
INTERCEPT_FUNCTION(OSSpinLockLock);
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 bf6a3a895bd3d4..8551424717de6d 100644
--- a/compiler-rt/lib/rtsan/tests/rtsan_test_interceptors_posix.cpp
+++ b/compiler-rt/lib/rtsan/tests/rtsan_test_interceptors_posix.cpp
@@ -20,7 +20,6 @@
#if SANITIZER_APPLE
#include <libkern/OSAtomic.h>
#include <os/lock.h>
-#include <sys/types.h>
#include <unistd.h>
#endif
@@ -38,12 +37,16 @@
#endif
#include <fcntl.h>
+#include <ifaddrs.h>
+#include <net/if.h>
#include <netdb.h>
#include <poll.h>
#include <pthread.h>
#include <stdio.h>
+#include <sys/ioctl.h>
#include <sys/mman.h>
#include <sys/socket.h>
+#include <sys/types.h>
#include <sys/uio.h>
#if _FILE_OFFSET_BITS == 64 && SANITIZER_GLIBC
@@ -373,6 +376,54 @@ class RtsanOpenedFileTest : public RtsanFileTest {
int fd = -1;
};
+TEST(TestRtsanInterceptors, IoctlDiesWhenRealtime) {
+ auto Func = []() { ioctl(0, FIONREAD); };
+ ExpectRealtimeDeath(Func, "ioctl");
+ ExpectNonRealtimeSurvival(Func);
+}
+
+TEST_F(RtsanOpenedFileTest, IoctlBehavesWithOutputArg) {
+ int arg{};
+ ioctl(GetOpenFd(), FIONREAD, &arg);
+
+ EXPECT_THAT(arg, Ge(0));
+}
+
+TEST(TestRtsanInterceptors, IoctlBehavesWithOutputPointer) {
+ // These initial checks just see if we CAN run these tests.
+ // If we can't (can't open a socket, or can't find an interface, just
+ // gracefully skip.
+ int sock = socket(AF_INET, SOCK_STREAM, 0);
+ if (sock == -1) {
+ perror("socket");
+ GTEST_SKIP();
+ }
+
+ struct ifaddrs *ifaddr = nullptr;
+ if (getifaddrs(&ifaddr) == -1 || ifaddr == nullptr) {
+ perror("getifaddrs");
+ close(sock);
+ GTEST_SKIP();
+ }
+
+ struct ifreq ifr {};
+ strncpy(ifr.ifr_name, ifaddr->ifa_name, IFNAMSIZ - 1);
+
+ int retval = ioctl(sock, SIOCGIFADDR, &ifr);
+ if (retval == -1) {
+ perror("ioctl");
+ close(sock);
+ freeifaddrs(ifaddr);
+ FAIL();
+ }
+
+ freeifaddrs(ifaddr);
+ close(sock);
+
+ ASSERT_THAT(ifr.ifr_addr.sa_data, NotNull());
+ ASSERT_THAT(ifr.ifr_addr.sa_family, Eq(AF_INET));
+}
+
TEST_F(RtsanOpenedFileTest, LseekDiesWhenRealtime) {
auto Func = [this]() { lseek(GetOpenFd(), 0, SEEK_SET); };
ExpectRealtimeDeath(Func, MAYBE_APPEND_64("lseek"));
More information about the llvm-commits
mailing list