diff --git a/compiler-rt/lib/rtsan/rtsan_interceptors_posix.cpp b/compiler-rt/lib/rtsan/rtsan_interceptors_posix.cpp index 5524197216719..c3fcd4f2da85c 100644 --- a/compiler-rt/lib/rtsan/rtsan_interceptors_posix.cpp +++ b/compiler-rt/lib/rtsan/rtsan_interceptors_posix.cpp @@ -535,6 +535,42 @@ INTERCEPTOR(int, shm_unlink, const char *name) { } // Sockets +INTERCEPTOR(int, getaddrinfo, const char *node, const char *service, + const struct addrinfo *hints, struct addrinfo **res) { + __rtsan_notify_intercepted_call("getaddrinfo"); + return REAL(getaddrinfo)(node, service, hints, res); +} + +INTERCEPTOR(int, getnameinfo, const struct sockaddr *sa, socklen_t salen, + char *host, socklen_t hostlen, char *serv, socklen_t servlen, + int flags) { + __rtsan_notify_intercepted_call("getnameinfo"); + return REAL(getnameinfo)(sa, salen, host, hostlen, serv, servlen, flags); +} + +INTERCEPTOR(int, bind, int socket, const struct sockaddr *address, + socklen_t address_len) { + __rtsan_notify_intercepted_call("bind"); + return REAL(bind)(socket, address, address_len); +} + +INTERCEPTOR(int, listen, int socket, int backlog) { + __rtsan_notify_intercepted_call("listen"); + return REAL(listen)(socket, backlog); +} + +INTERCEPTOR(int, accept, int socket, struct sockaddr *address, + socklen_t *address_len) { + __rtsan_notify_intercepted_call("accept"); + return REAL(accept)(socket, address, address_len); +} + +INTERCEPTOR(int, connect, int socket, const struct sockaddr *address, + socklen_t address_len) { + __rtsan_notify_intercepted_call("connect"); + return REAL(connect)(socket, address, address_len); +} + INTERCEPTOR(int, socket, int domain, int type, int protocol) { __rtsan_notify_intercepted_call("socket"); return REAL(socket)(domain, type, protocol); @@ -648,14 +684,20 @@ void __rtsan::InitializeInterceptors() { INTERCEPT_FUNCTION(usleep); INTERCEPT_FUNCTION(nanosleep); - INTERCEPT_FUNCTION(socket); + INTERCEPT_FUNCTION(accept); + INTERCEPT_FUNCTION(bind); + INTERCEPT_FUNCTION(connect); + INTERCEPT_FUNCTION(getaddrinfo); + INTERCEPT_FUNCTION(getnameinfo); + INTERCEPT_FUNCTION(listen); + INTERCEPT_FUNCTION(recv); + INTERCEPT_FUNCTION(recvfrom); + INTERCEPT_FUNCTION(recvmsg); INTERCEPT_FUNCTION(send); INTERCEPT_FUNCTION(sendmsg); INTERCEPT_FUNCTION(sendto); - INTERCEPT_FUNCTION(recv); - INTERCEPT_FUNCTION(recvmsg); - INTERCEPT_FUNCTION(recvfrom); INTERCEPT_FUNCTION(shutdown); + INTERCEPT_FUNCTION(socket); } #endif // SANITIZER_POSIX 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 1850f4fa30f9c..d0ae12c9bea44 100644 --- a/compiler-rt/lib/rtsan/tests/rtsan_test_interceptors_posix.cpp +++ b/compiler-rt/lib/rtsan/tests/rtsan_test_interceptors_posix.cpp @@ -29,6 +29,7 @@ #endif #include +#include #include #include #include @@ -46,6 +47,11 @@ using namespace testing; using namespace rtsan_testing; using namespace std::chrono_literals; +// NOTE: In the socket tests we pass in bad info to the calls to ensure they +// fail which is why we EXPECT_NE 0 for their return codes. +// We just care that the call is intercepted +const int kNotASocketFd = 0; + void *FakeThreadEntryPoint(void *) { return nullptr; } class RtsanFileTest : public ::testing::Test { @@ -676,6 +682,49 @@ TEST_F(PthreadRwlockTest, PthreadRwlockWrlockSurvivesWhenNonRealtime) { /* Sockets */ +TEST(TestRtsanInterceptors, GetAddrInfoDiesWhenRealtime) { + auto Func = []() { + addrinfo *info{}; + getaddrinfo("localhost", "http", nullptr, &info); + }; + ExpectRealtimeDeath(Func, "getaddrinfo"); + ExpectNonRealtimeSurvival(Func); +} + +TEST(TestRtsanInterceptors, GetNameInfoDiesWhenRealtime) { + auto Func = []() { + char host[NI_MAXHOST]; + char serv[NI_MAXSERV]; + getnameinfo(nullptr, 0, host, NI_MAXHOST, serv, NI_MAXSERV, 0); + }; + ExpectRealtimeDeath(Func, "getnameinfo"); + ExpectNonRealtimeSurvival(Func); +} + +TEST(TestRtsanInterceptors, BindingASocketDiesWhenRealtime) { + auto Func = []() { EXPECT_NE(bind(kNotASocketFd, nullptr, 0), 0); }; + ExpectRealtimeDeath(Func, "bind"); + ExpectNonRealtimeSurvival(Func); +} + +TEST(TestRtsanInterceptors, ListeningOnASocketDiesWhenRealtime) { + auto Func = []() { EXPECT_NE(listen(kNotASocketFd, 0), 0); }; + ExpectRealtimeDeath(Func, "listen"); + ExpectNonRealtimeSurvival(Func); +} + +TEST(TestRtsanInterceptors, AcceptingASocketDiesWhenRealtime) { + auto Func = []() { EXPECT_LT(accept(kNotASocketFd, nullptr, nullptr), 0); }; + ExpectRealtimeDeath(Func, "accept"); + ExpectNonRealtimeSurvival(Func); +} + +TEST(TestRtsanInterceptors, ConnectingASocketDiesWhenRealtime) { + auto Func = []() { EXPECT_NE(connect(kNotASocketFd, nullptr, 0), 0); }; + ExpectRealtimeDeath(Func, "connect"); + ExpectNonRealtimeSurvival(Func); +} + TEST(TestRtsanInterceptors, OpeningASocketDiesWhenRealtime) { auto Func = []() { socket(PF_INET, SOCK_STREAM, 0); }; ExpectRealtimeDeath(Func, "socket");