Skip to content

Commit 15f5450

Browse files
committed
[𝘀𝗽𝗿] initial version
Created using spr 1.3.4
1 parent 3142dff commit 15f5450

File tree

2 files changed

+45
-18
lines changed

2 files changed

+45
-18
lines changed

compiler-rt/lib/sanitizer_common/sanitizer_posix_libcdep.cpp

Lines changed: 34 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -288,26 +288,42 @@ bool SignalContext::IsStackOverflow() const {
288288

289289
#endif // SANITIZER_GO
290290

291+
static void SetNonBlock(int fd) {
292+
int res = fcntl(fd, F_GETFL, 0);
293+
CHECK(!internal_iserror(res, nullptr));
294+
295+
res |= O_NONBLOCK;
296+
res = fcntl(fd, F_SETFL, res);
297+
CHECK(!internal_iserror(res, nullptr));
298+
}
299+
291300
bool IsAccessibleMemoryRange(uptr beg, uptr size) {
292-
uptr page_size = GetPageSizeCached();
293-
// Checking too large memory ranges is slow.
294-
CHECK_LT(size, page_size * 10);
295-
int sock_pair[2];
296-
if (pipe(sock_pair))
297-
return false;
298-
uptr bytes_written =
299-
internal_write(sock_pair[1], reinterpret_cast<void *>(beg), size);
300-
int write_errno;
301-
bool result;
302-
if (internal_iserror(bytes_written, &write_errno)) {
303-
CHECK_EQ(EFAULT, write_errno);
304-
result = false;
305-
} else {
306-
result = (bytes_written == size);
301+
for (uptr to_write = size; to_write;) {
302+
// `read` from `sock_pair[0]` into a dummy buffer to free up the pipe buffer
303+
// for more `write` is slower than just recreating a pipe.
304+
int sock_pair[2];
305+
if (pipe(sock_pair))
306+
return false;
307+
308+
auto cleanup = at_scope_exit([&]() {
309+
internal_close(sock_pair[0]);
310+
internal_close(sock_pair[1]);
311+
});
312+
313+
SetNonBlock(sock_pair[1]);
314+
315+
int write_errno;
316+
uptr bytes_written =
317+
internal_write(sock_pair[1], reinterpret_cast<char *>(beg), to_write);
318+
if (internal_iserror(bytes_written, &write_errno)) {
319+
CHECK_EQ(EFAULT, write_errno);
320+
return false;
321+
}
322+
beg += bytes_written;
323+
to_write -= bytes_written;
307324
}
308-
internal_close(sock_pair[0]);
309-
internal_close(sock_pair[1]);
310-
return result;
325+
326+
return true;
311327
}
312328

313329
void PlatformPrepareForSandboxing(void *args) {

compiler-rt/lib/sanitizer_common/tests/sanitizer_posix_test.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,17 @@ TEST(SanitizerCommon, IsAccessibleMemoryRange) {
8282
munmap((void *)mem, 3 * page_size);
8383
}
8484

85+
TEST(SanitizerCommon, IsAccessibleMemoryRangeLarge) {
86+
const int size = GetPageSize() * 10000;
87+
88+
uptr mem = (uptr)mmap(0, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON,
89+
-1, 0);
90+
91+
EXPECT_TRUE(IsAccessibleMemoryRange(mem, size));
92+
93+
munmap((void *)mem, size);
94+
}
95+
8596
} // namespace __sanitizer
8697

8798
#endif // SANITIZER_POSIX

0 commit comments

Comments
 (0)