Skip to content

Commit 556e9d0

Browse files
authored
[rtsan][compiler-rt] Add read, write, pread, pwrite, readv, and writev interceptors (#106161)
1 parent c992690 commit 556e9d0

File tree

2 files changed

+129
-17
lines changed

2 files changed

+129
-17
lines changed

compiler-rt/lib/rtsan/rtsan_interceptors.cpp

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,37 @@ INTERCEPTOR(int, puts, const char *s) {
161161
return REAL(puts)(s);
162162
}
163163

164+
INTERCEPTOR(ssize_t, read, int fd, void *buf, size_t count) {
165+
ExpectNotRealtime("read");
166+
return REAL(read)(fd, buf, count);
167+
}
168+
169+
INTERCEPTOR(ssize_t, write, int fd, const void *buf, size_t count) {
170+
ExpectNotRealtime("write");
171+
return REAL(write)(fd, buf, count);
172+
}
173+
174+
INTERCEPTOR(ssize_t, pread, int fd, void *buf, size_t count, off_t offset) {
175+
ExpectNotRealtime("pread");
176+
return REAL(pread)(fd, buf, count, offset);
177+
}
178+
179+
INTERCEPTOR(ssize_t, readv, int fd, const struct iovec *iov, int iovcnt) {
180+
ExpectNotRealtime("readv");
181+
return REAL(readv)(fd, iov, iovcnt);
182+
}
183+
184+
INTERCEPTOR(ssize_t, pwrite, int fd, const void *buf, size_t count,
185+
off_t offset) {
186+
ExpectNotRealtime("pwrite");
187+
return REAL(pwrite)(fd, buf, count, offset);
188+
}
189+
190+
INTERCEPTOR(ssize_t, writev, int fd, const struct iovec *iov, int iovcnt) {
191+
ExpectNotRealtime("writev");
192+
return REAL(writev)(fd, iov, iovcnt);
193+
}
194+
164195
// Concurrency
165196
#if SANITIZER_APPLE
166197
#pragma clang diagnostic push
@@ -400,6 +431,12 @@ void __rtsan::InitializeInterceptors() {
400431
INTERCEPT_FUNCTION(close);
401432
INTERCEPT_FUNCTION(fopen);
402433
INTERCEPT_FUNCTION(fread);
434+
INTERCEPT_FUNCTION(read);
435+
INTERCEPT_FUNCTION(write);
436+
INTERCEPT_FUNCTION(pread);
437+
INTERCEPT_FUNCTION(readv);
438+
INTERCEPT_FUNCTION(pwrite);
439+
INTERCEPT_FUNCTION(writev);
403440
INTERCEPT_FUNCTION(fwrite);
404441
INTERCEPT_FUNCTION(fclose);
405442
INTERCEPT_FUNCTION(fcntl);

compiler-rt/lib/rtsan/tests/rtsan_test_interceptors.cpp

Lines changed: 92 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
#if SANITIZER_APPLE
1919
#include <libkern/OSAtomic.h>
2020
#include <os/lock.h>
21+
#include <sys/types.h>
22+
#include <unistd.h>
2123
#endif
2224

2325
#if SANITIZER_INTERCEPT_MEMALIGN || SANITIZER_INTERCEPT_PVALLOC
@@ -33,6 +35,7 @@
3335
#include <pthread.h>
3436
#include <stdio.h>
3537
#include <sys/socket.h>
38+
#include <sys/uio.h>
3639

3740
using namespace testing;
3841
using namespace rtsan_testing;
@@ -280,23 +283,43 @@ TEST_F(RtsanFileTest, FopenDiesWhenRealtime) {
280283
ExpectNonRealtimeSurvival(func);
281284
}
282285

283-
TEST_F(RtsanFileTest, FreadDiesWhenRealtime) {
284-
auto fd = fopen(GetTemporaryFilePath(), "w");
285-
auto func = [fd]() {
286+
class RtsanOpenedFileTest : public RtsanFileTest {
287+
protected:
288+
void SetUp() override {
289+
RtsanFileTest::SetUp();
290+
file = fopen(GetTemporaryFilePath(), "w");
291+
ASSERT_THAT(file, Ne(nullptr));
292+
fd = fileno(file);
293+
ASSERT_THAT(fd, Ne(-1));
294+
}
295+
296+
void TearDown() override {
297+
if (file != nullptr)
298+
fclose(file);
299+
RtsanFileTest::TearDown();
300+
}
301+
302+
FILE *GetOpenFile() { return file; }
303+
304+
int GetOpenFd() { return fd; }
305+
306+
private:
307+
FILE *file = nullptr;
308+
int fd = -1;
309+
};
310+
311+
TEST_F(RtsanOpenedFileTest, FreadDiesWhenRealtime) {
312+
auto func = [this]() {
286313
char c{};
287-
fread(&c, 1, 1, fd);
314+
fread(&c, 1, 1, GetOpenFile());
288315
};
289316
ExpectRealtimeDeath(func, "fread");
290317
ExpectNonRealtimeSurvival(func);
291-
if (fd != nullptr)
292-
fclose(fd);
293318
}
294319

295-
TEST_F(RtsanFileTest, FwriteDiesWhenRealtime) {
296-
auto fd = fopen(GetTemporaryFilePath(), "w");
297-
ASSERT_NE(nullptr, fd);
298-
auto message = "Hello, world!";
299-
auto func = [&]() { fwrite(&message, 1, 4, fd); };
320+
TEST_F(RtsanOpenedFileTest, FwriteDiesWhenRealtime) {
321+
const char *message = "Hello, world!";
322+
auto func = [&]() { fwrite(&message, 1, 4, GetOpenFile()); };
300323
ExpectRealtimeDeath(func, "fwrite");
301324
ExpectNonRealtimeSurvival(func);
302325
}
@@ -315,14 +338,66 @@ TEST(TestRtsanInterceptors, PutsDiesWhenRealtime) {
315338
ExpectNonRealtimeSurvival(func);
316339
}
317340

318-
TEST_F(RtsanFileTest, FputsDiesWhenRealtime) {
319-
auto fd = fopen(GetTemporaryFilePath(), "w");
320-
ASSERT_THAT(fd, Ne(nullptr)) << errno;
321-
auto func = [fd]() { fputs("Hello, world!\n", fd); };
341+
TEST_F(RtsanOpenedFileTest, FputsDiesWhenRealtime) {
342+
auto func = [this]() { fputs("Hello, world!\n", GetOpenFile()); };
322343
ExpectRealtimeDeath(func);
323344
ExpectNonRealtimeSurvival(func);
324-
if (fd != nullptr)
325-
fclose(fd);
345+
}
346+
347+
TEST_F(RtsanOpenedFileTest, ReadDiesWhenRealtime) {
348+
auto Func = [this]() {
349+
char c{};
350+
read(GetOpenFd(), &c, 1);
351+
};
352+
ExpectRealtimeDeath(Func, "read");
353+
ExpectNonRealtimeSurvival(Func);
354+
}
355+
356+
TEST_F(RtsanOpenedFileTest, WriteDiesWhenRealtime) {
357+
auto Func = [this]() {
358+
char c = 'a';
359+
write(GetOpenFd(), &c, 1);
360+
};
361+
ExpectRealtimeDeath(Func, "write");
362+
ExpectNonRealtimeSurvival(Func);
363+
}
364+
365+
TEST_F(RtsanOpenedFileTest, PreadDiesWhenRealtime) {
366+
auto Func = [this]() {
367+
char c{};
368+
pread(GetOpenFd(), &c, 1, 0);
369+
};
370+
ExpectRealtimeDeath(Func, "pread");
371+
ExpectNonRealtimeSurvival(Func);
372+
}
373+
374+
TEST_F(RtsanOpenedFileTest, ReadvDiesWhenRealtime) {
375+
auto Func = [this]() {
376+
char c{};
377+
iovec iov{&c, 1};
378+
readv(GetOpenFd(), &iov, 1);
379+
};
380+
ExpectRealtimeDeath(Func, "readv");
381+
ExpectNonRealtimeSurvival(Func);
382+
}
383+
384+
TEST_F(RtsanOpenedFileTest, PwriteDiesWhenRealtime) {
385+
auto Func = [this]() {
386+
char c = 'a';
387+
pwrite(GetOpenFd(), &c, 1, 0);
388+
};
389+
ExpectRealtimeDeath(Func, "pwrite");
390+
ExpectNonRealtimeSurvival(Func);
391+
}
392+
393+
TEST_F(RtsanOpenedFileTest, WritevDiesWhenRealtime) {
394+
auto Func = [this]() {
395+
char c = 'a';
396+
iovec iov{&c, 1};
397+
writev(GetOpenFd(), &iov, 1);
398+
};
399+
ExpectRealtimeDeath(Func, "writev");
400+
ExpectNonRealtimeSurvival(Func);
326401
}
327402

328403
/*

0 commit comments

Comments
 (0)