[compiler-rt] [sanitizer] Make internal_close_range available on all POSIX platforms (PR #191971)

via llvm-commits llvm-commits at lists.llvm.org
Mon Apr 13 23:59:13 PDT 2026


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-compiler-rt-sanitizer

Author: Paweł Bylica (chfast)

<details>
<summary>Changes</summary>

Make internal_close_range available on all POSIX platforms so callers can use it without platform-specific #if guards. Platforms without close_range return -1, letting callers fall back gracefully.

Update StartSubprocess to try close_range first with a fallback to the slow sysconf(_SC_OPEN_MAX) loop.

Currently only FreeBSD has a real implementation. A TODO is left for adding Linux support (__NR_close_range, kernel 5.9+).

The Linux support will be added in https://github.com/llvm/llvm-project/pull/191450.




---
Full diff: https://github.com/llvm/llvm-project/pull/191971.diff


7 Files Affected:

- (modified) compiler-rt/lib/sanitizer_common/sanitizer_haiku.cpp (+4) 
- (modified) compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp (+5-2) 
- (modified) compiler-rt/lib/sanitizer_common/sanitizer_mac.cpp (+4) 
- (modified) compiler-rt/lib/sanitizer_common/sanitizer_netbsd.cpp (+4) 
- (modified) compiler-rt/lib/sanitizer_common/sanitizer_posix.h (+2-2) 
- (modified) compiler-rt/lib/sanitizer_common/sanitizer_posix_libcdep.cpp (+4-5) 
- (modified) compiler-rt/lib/sanitizer_common/sanitizer_solaris.cpp (+4) 


``````````diff
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_haiku.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_haiku.cpp
index 7c114417560e5..b48ad5e14aa03 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_haiku.cpp
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_haiku.cpp
@@ -128,6 +128,10 @@ uptr internal_close(fd_t fd) {
   RETURN_AND_SET_ERRNO(_kern_close(fd));
 }
 
+uptr internal_close_range(fd_t lowfd, fd_t highfd, int flags) {
+  return -1;  // Not supported.
+}
+
 uptr internal_open(const char *filename, int flags) {
   CHECK(&_kern_open);
   RETURN_AND_SET_ERRNO(_kern_open(-1, filename, flags, 0));
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp
index 16b94ea901bad..cc95c7b6aa54e 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp
@@ -306,11 +306,14 @@ int internal_madvise(uptr addr, uptr length, int advice) {
   return internal_syscall(SYSCALL(madvise), addr, length, advice);
 }
 
-#    if SANITIZER_FREEBSD
 uptr internal_close_range(fd_t lowfd, fd_t highfd, int flags) {
+#    if SANITIZER_FREEBSD
   return internal_syscall(SYSCALL(close_range), lowfd, highfd, flags);
-}
+#    else
+  // TODO: Add Linux support using __NR_close_range (available since 5.9).
+  return -1;  // Not supported.
 #    endif
+}
 uptr internal_close(fd_t fd) { return internal_syscall(SYSCALL(close), fd); }
 
 uptr internal_open(const char *filename, int flags) {
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_mac.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_mac.cpp
index 940175791f376..6fafc04f557b4 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_mac.cpp
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_mac.cpp
@@ -170,6 +170,10 @@ uptr internal_close(fd_t fd) {
   return close(fd);
 }
 
+uptr internal_close_range(fd_t lowfd, fd_t highfd, int flags) {
+  return -1;  // Not supported.
+}
+
 uptr internal_open(const char *filename, int flags) {
   return open(filename, flags);
 }
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_netbsd.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_netbsd.cpp
index 737e336dfbe87..d83adc34c9ac6 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_netbsd.cpp
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_netbsd.cpp
@@ -126,6 +126,10 @@ uptr internal_close(fd_t fd) {
   return _sys_close(fd);
 }
 
+uptr internal_close_range(fd_t lowfd, fd_t highfd, int flags) {
+  return -1;  // Not supported.
+}
+
 uptr internal_open(const char *filename, int flags) {
   CHECK(&_sys_open);
   return _sys_open(filename, flags);
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_posix.h b/compiler-rt/lib/sanitizer_common/sanitizer_posix.h
index dc9c3b8822d30..2c3cd40f5019d 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_posix.h
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_posix.h
@@ -28,9 +28,9 @@ namespace __sanitizer {
 // Don't use directly, use __sanitizer::OpenFile() instead.
 uptr internal_open(const char *filename, int flags);
 uptr internal_open(const char *filename, int flags, u32 mode);
-#  if SANITIZER_FREEBSD
+// Closes all file descriptors from lowfd to highfd (inclusive).
+// Returns 0 on success or non-zero if not supported on this platform.
 uptr internal_close_range(fd_t lowfd, fd_t highfd, int flags);
-#  endif
 uptr internal_close(fd_t fd);
 
 uptr internal_read(fd_t fd, void *buf, uptr count);
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_posix_libcdep.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_posix_libcdep.cpp
index 8e5e87938c372..eb18320ce000f 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_posix_libcdep.cpp
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_posix_libcdep.cpp
@@ -562,11 +562,10 @@ pid_t StartSubprocess(const char *program, const char *const argv[],
       internal_close(stderr_fd);
     }
 
-#  if SANITIZER_FREEBSD
-    internal_close_range(3, ~static_cast<fd_t>(0), 0);
-#  else
-    for (int fd = sysconf(_SC_OPEN_MAX); fd > 2; fd--) internal_close(fd);
-#  endif
+    // Use close_range to avoid a slow loop when RLIMIT_NOFILE is high.
+    // Falls back to the loop if not available on this platform/kernel.
+    if (internal_close_range(3, ~static_cast<fd_t>(0), 0) != 0)
+      for (int fd = sysconf(_SC_OPEN_MAX); fd > 2; fd--) internal_close(fd);
 
     internal_execve(program, const_cast<char **>(&argv[0]),
                     const_cast<char *const *>(envp));
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_solaris.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_solaris.cpp
index 62c40affc9ac5..fe9ca92831e22 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_solaris.cpp
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_solaris.cpp
@@ -102,6 +102,10 @@ uptr internal_open(const char *filename, int flags, u32 mode) {
   return _REAL64(open)(filename, flags, mode);
 }
 
+uptr internal_close_range(fd_t lowfd, fd_t highfd, int flags) {
+  return -1;  // Not supported.
+}
+
 DECLARE__REAL_AND_INTERNAL(uptr, read, fd_t fd, void *buf, uptr count) {
   return _REAL(read)(fd, buf, count);
 }

``````````

</details>


https://github.com/llvm/llvm-project/pull/191971


More information about the llvm-commits mailing list