|
20 | 20 | #if SANITIZER_APPLE |
21 | 21 | #include <libkern/OSAtomic.h> |
22 | 22 | #include <os/lock.h> |
23 | | -#include <sys/types.h> |
24 | 23 | #include <unistd.h> |
25 | 24 | #endif |
26 | 25 |
|
|
38 | 37 | #endif |
39 | 38 |
|
40 | 39 | #include <fcntl.h> |
| 40 | +#include <ifaddrs.h> |
| 41 | +#include <net/if.h> |
41 | 42 | #include <netdb.h> |
42 | 43 | #include <poll.h> |
43 | 44 | #include <pthread.h> |
44 | 45 | #include <stdio.h> |
| 46 | +#include <sys/ioctl.h> |
45 | 47 | #include <sys/mman.h> |
46 | 48 | #include <sys/socket.h> |
| 49 | +#include <sys/types.h> |
47 | 50 | #include <sys/uio.h> |
48 | 51 |
|
49 | 52 | #if _FILE_OFFSET_BITS == 64 && SANITIZER_GLIBC |
@@ -245,7 +248,6 @@ TEST(TestRtsanInterceptors, SchedYieldDiesWhenRealtime) { |
245 | 248 | /* |
246 | 249 | Filesystem |
247 | 250 | */ |
248 | | - |
249 | 251 | TEST_F(RtsanFileTest, OpenDiesWhenRealtime) { |
250 | 252 | auto Func = [this]() { open(GetTemporaryFilePath(), O_RDONLY); }; |
251 | 253 | ExpectRealtimeDeath(Func, MAYBE_APPEND_64("open")); |
@@ -373,6 +375,57 @@ class RtsanOpenedFileTest : public RtsanFileTest { |
373 | 375 | int fd = -1; |
374 | 376 | }; |
375 | 377 |
|
| 378 | +TEST(TestRtsanInterceptors, IoctlDiesWhenRealtime) { |
| 379 | + auto Func = []() { ioctl(0, FIONREAD); }; |
| 380 | + ExpectRealtimeDeath(Func, "ioctl"); |
| 381 | + ExpectNonRealtimeSurvival(Func); |
| 382 | +} |
| 383 | + |
| 384 | +TEST_F(RtsanOpenedFileTest, IoctlBehavesWithOutputArg) { |
| 385 | + int arg{}; |
| 386 | + ioctl(GetOpenFd(), FIONREAD, &arg); |
| 387 | + |
| 388 | + EXPECT_THAT(arg, Ge(0)); |
| 389 | +} |
| 390 | + |
| 391 | +TEST(TestRtsanInterceptors, IoctlBehavesWithOutputPointer) { |
| 392 | + // These initial checks just see if we CAN run these tests. |
| 393 | + // If we can't (can't open a socket, or can't find an interface, just |
| 394 | + // gracefully skip. |
| 395 | + int sock = socket(AF_INET, SOCK_STREAM, 0); |
| 396 | + if (sock == -1) { |
| 397 | + perror("socket"); |
| 398 | + GTEST_SKIP(); |
| 399 | + return; |
| 400 | + } |
| 401 | + |
| 402 | + struct ifaddrs *ifaddr = nullptr; |
| 403 | + if (getifaddrs(&ifaddr) == -1 || ifaddr == nullptr) { |
| 404 | + perror("getifaddrs"); |
| 405 | + close(sock); |
| 406 | + GTEST_SKIP(); |
| 407 | + return; |
| 408 | + } |
| 409 | + |
| 410 | + struct ifreq ifr {}; |
| 411 | + strncpy(ifr.ifr_name, ifaddr->ifa_name, IFNAMSIZ - 1); |
| 412 | + |
| 413 | + int retval = ioctl(sock, SIOCGIFADDR, &ifr); |
| 414 | + if (retval == -1) { |
| 415 | + perror("ioctl"); |
| 416 | + close(sock); |
| 417 | + freeifaddrs(ifaddr); |
| 418 | + ASSERT_TRUE(false) << "ioctl failed"; |
| 419 | + return; |
| 420 | + } |
| 421 | + |
| 422 | + freeifaddrs(ifaddr); |
| 423 | + close(sock); |
| 424 | + |
| 425 | + ASSERT_THAT(ifr.ifr_addr.sa_data, NotNull()); |
| 426 | + ASSERT_THAT(ifr.ifr_addr.sa_family, Eq(AF_INET)); |
| 427 | +} |
| 428 | + |
376 | 429 | TEST_F(RtsanOpenedFileTest, LseekDiesWhenRealtime) { |
377 | 430 | auto Func = [this]() { lseek(GetOpenFd(), 0, SEEK_SET); }; |
378 | 431 | ExpectRealtimeDeath(Func, MAYBE_APPEND_64("lseek")); |
|
0 commit comments