[compiler-rt] [sanitizer] Large range support in IsAccessibleMemoryRange (PR #112665)
Vitaly Buka via llvm-commits
llvm-commits at lists.llvm.org
Thu Oct 17 10:44:57 PDT 2024
https://github.com/vitalybuka updated https://github.com/llvm/llvm-project/pull/112665
>From 15f54502722a07b4c69ad079934a179d71b840ac Mon Sep 17 00:00:00 2001
From: Vitaly Buka <vitalybuka at google.com>
Date: Wed, 16 Oct 2024 23:06:02 -0700
Subject: [PATCH 1/2] =?UTF-8?q?[=F0=9D=98=80=F0=9D=97=BD=F0=9D=97=BF]=20in?=
=?UTF-8?q?itial=20version?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Created using spr 1.3.4
---
.../sanitizer_posix_libcdep.cpp | 52 ++++++++++++-------
.../tests/sanitizer_posix_test.cpp | 11 ++++
2 files changed, 45 insertions(+), 18 deletions(-)
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_posix_libcdep.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_posix_libcdep.cpp
index 9ffb36f812c45d..0f8fdd4487efb6 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_posix_libcdep.cpp
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_posix_libcdep.cpp
@@ -288,26 +288,42 @@ bool SignalContext::IsStackOverflow() const {
#endif // SANITIZER_GO
+static void SetNonBlock(int fd) {
+ int res = fcntl(fd, F_GETFL, 0);
+ CHECK(!internal_iserror(res, nullptr));
+
+ res |= O_NONBLOCK;
+ res = fcntl(fd, F_SETFL, res);
+ CHECK(!internal_iserror(res, nullptr));
+}
+
bool IsAccessibleMemoryRange(uptr beg, uptr size) {
- uptr page_size = GetPageSizeCached();
- // Checking too large memory ranges is slow.
- CHECK_LT(size, page_size * 10);
- int sock_pair[2];
- if (pipe(sock_pair))
- return false;
- uptr bytes_written =
- internal_write(sock_pair[1], reinterpret_cast<void *>(beg), size);
- int write_errno;
- bool result;
- if (internal_iserror(bytes_written, &write_errno)) {
- CHECK_EQ(EFAULT, write_errno);
- result = false;
- } else {
- result = (bytes_written == size);
+ for (uptr to_write = size; to_write;) {
+ // `read` from `sock_pair[0]` into a dummy buffer to free up the pipe buffer
+ // for more `write` is slower than just recreating a pipe.
+ int sock_pair[2];
+ if (pipe(sock_pair))
+ return false;
+
+ auto cleanup = at_scope_exit([&]() {
+ internal_close(sock_pair[0]);
+ internal_close(sock_pair[1]);
+ });
+
+ SetNonBlock(sock_pair[1]);
+
+ int write_errno;
+ uptr bytes_written =
+ internal_write(sock_pair[1], reinterpret_cast<char *>(beg), to_write);
+ if (internal_iserror(bytes_written, &write_errno)) {
+ CHECK_EQ(EFAULT, write_errno);
+ return false;
+ }
+ beg += bytes_written;
+ to_write -= bytes_written;
}
- internal_close(sock_pair[0]);
- internal_close(sock_pair[1]);
- return result;
+
+ return true;
}
void PlatformPrepareForSandboxing(void *args) {
diff --git a/compiler-rt/lib/sanitizer_common/tests/sanitizer_posix_test.cpp b/compiler-rt/lib/sanitizer_common/tests/sanitizer_posix_test.cpp
index bed19d15a8ec77..9feb22221f005e 100644
--- a/compiler-rt/lib/sanitizer_common/tests/sanitizer_posix_test.cpp
+++ b/compiler-rt/lib/sanitizer_common/tests/sanitizer_posix_test.cpp
@@ -82,6 +82,17 @@ TEST(SanitizerCommon, IsAccessibleMemoryRange) {
munmap((void *)mem, 3 * page_size);
}
+TEST(SanitizerCommon, IsAccessibleMemoryRangeLarge) {
+ const int size = GetPageSize() * 10000;
+
+ uptr mem = (uptr)mmap(0, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON,
+ -1, 0);
+
+ EXPECT_TRUE(IsAccessibleMemoryRange(mem, size));
+
+ munmap((void *)mem, size);
+}
+
} // namespace __sanitizer
#endif // SANITIZER_POSIX
>From 8652b674755dca83a6f8b1a97f7b4417b6ce936a Mon Sep 17 00:00:00 2001
From: Vitaly Buka <vitalybuka at google.com>
Date: Wed, 16 Oct 2024 23:15:55 -0700
Subject: [PATCH 2/2] simplify
Created using spr 1.3.4
---
.../lib/sanitizer_common/sanitizer_posix_libcdep.cpp | 11 +++++------
1 file changed, 5 insertions(+), 6 deletions(-)
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_posix_libcdep.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_posix_libcdep.cpp
index 0f8fdd4487efb6..f87af4bb3a5a6a 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_posix_libcdep.cpp
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_posix_libcdep.cpp
@@ -298,7 +298,7 @@ static void SetNonBlock(int fd) {
}
bool IsAccessibleMemoryRange(uptr beg, uptr size) {
- for (uptr to_write = size; to_write;) {
+ while (size) {
// `read` from `sock_pair[0]` into a dummy buffer to free up the pipe buffer
// for more `write` is slower than just recreating a pipe.
int sock_pair[2];
@@ -313,14 +313,13 @@ bool IsAccessibleMemoryRange(uptr beg, uptr size) {
SetNonBlock(sock_pair[1]);
int write_errno;
- uptr bytes_written =
- internal_write(sock_pair[1], reinterpret_cast<char *>(beg), to_write);
- if (internal_iserror(bytes_written, &write_errno)) {
+ uptr w = internal_write(sock_pair[1], reinterpret_cast<char *>(beg), size);
+ if (internal_iserror(w, &write_errno)) {
CHECK_EQ(EFAULT, write_errno);
return false;
}
- beg += bytes_written;
- to_write -= bytes_written;
+ size -= w;
+ beg += w;
}
return true;
More information about the llvm-commits
mailing list