[compiler-rt] 7086584 - [sanitizer] Large range support in IsAccessibleMemoryRange (#112665)

via llvm-commits llvm-commits at lists.llvm.org
Thu Oct 17 13:07:06 PDT 2024


Author: Vitaly Buka
Date: 2024-10-17T13:07:02-07:00
New Revision: 70865844cbf619e1f4011cd3383a028ab4ec2081

URL: https://github.com/llvm/llvm-project/commit/70865844cbf619e1f4011cd3383a028ab4ec2081
DIFF: https://github.com/llvm/llvm-project/commit/70865844cbf619e1f4011cd3383a028ab4ec2081.diff

LOG: [sanitizer] Large range support in IsAccessibleMemoryRange (#112665)

The comment stated that it's slow, but likely it's a deadlock,
as write can be blocked.

Also we can't be sure that `page_size * 10` is appropriate size.

Still most likely this is NFC, as the max `size` we use is 32,
and should fit in any buffer.

Added: 
    

Modified: 
    compiler-rt/lib/sanitizer_common/sanitizer_posix_libcdep.cpp
    compiler-rt/lib/sanitizer_common/tests/sanitizer_posix_test.cpp

Removed: 
    


################################################################################
diff  --git a/compiler-rt/lib/sanitizer_common/sanitizer_posix_libcdep.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_posix_libcdep.cpp
index 9ffb36f812c45d..3ab83977a4ee23 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);
+  while (size) {
+    // `read` from `fds[0]` into a dummy buffer to free up the pipe buffer for
+    // more `write` is slower than just recreating a pipe.
+    int fds[2];
+    CHECK_EQ(0, pipe(fds));
+
+    auto cleanup = at_scope_exit([&]() {
+      internal_close(fds[0]);
+      internal_close(fds[1]);
+    });
+
+    SetNonBlock(fds[1]);
+
+    int write_errno;
+    uptr w = internal_write(fds[1], reinterpret_cast<char *>(beg), size);
+    if (internal_iserror(w, &write_errno)) {
+      if (write_errno == EINTR)
+        continue;
+      CHECK_EQ(EFAULT, write_errno);
+      return false;
+    }
+    size -= w;
+    beg += w;
   }
-  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 803c8d39362e27..04890f2f5e2af2 100644
--- a/compiler-rt/lib/sanitizer_common/tests/sanitizer_posix_test.cpp
+++ b/compiler-rt/lib/sanitizer_common/tests/sanitizer_posix_test.cpp
@@ -80,6 +80,12 @@ TEST(SanitizerCommon, IsAccessibleMemoryRange) {
   EXPECT_FALSE(IsAccessibleMemoryRange(0x0, 2));
 }
 
+TEST(SanitizerCommon, IsAccessibleMemoryRangeLarge) {
+  InternalMmapVector<char> buffer(10000 * GetPageSize());
+  EXPECT_TRUE(IsAccessibleMemoryRange(reinterpret_cast<uptr>(buffer.data()),
+                                      buffer.size()));
+}
+
 }  // namespace __sanitizer
 
 #endif  // SANITIZER_POSIX


        


More information about the llvm-commits mailing list