]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
FreeBSD close_range syscall
authorPaul Floyd <pjfloyd@wanadoo.fr>
Fri, 2 May 2025 14:59:58 +0000 (16:59 +0200)
committerPaul Floyd <pjfloyd@wanadoo.fr>
Fri, 2 May 2025 15:02:28 +0000 (17:02 +0200)
Simplify the checking. No ned to test for reserved fds,
and just split the close_range if debug output is enabled.

Add a call to close_range with an upper bound of ~0U in the
testcase.

These changes will probably be the basis for fixing
https://bugs.kde.org/show_bug.cgi?id=503641

coregrind/m_syswrap/syswrap-freebsd.c
memcheck/tests/close_range.c
memcheck/tests/close_range.stderr.exp

index 7ea04fdbc6bea447175f324a3522bf286ab429c5..41cd0756196b292878811e0ace974e31d7a6bec3 100644 (file)
@@ -6615,10 +6615,8 @@ POST(sys___realpathat)
 // int close_range(u_int lowfd, u_int highfd, int flags);
 PRE(sys_close_range)
 {
-   SysRes res = VG_(mk_SysRes_Success)(0);
-   unsigned int lowfd = ARG1;
-   unsigned int fd_counter; // will count from lowfd to highfd
-   unsigned int highfd = ARG2;
+   UInt lowfd = ARG1;
+   UInt highfd = ARG2;
 
    /* on linux the may lock if futexes are used
     * there is a lock in the kernel but I assume it's just
@@ -6642,46 +6640,48 @@ PRE(sys_close_range)
       return;
    }
 
-   fd_counter = lowfd;
-   do {
-      if (fd_counter > highfd
-          || (fd_counter == 2U/*stderr*/ && VG_(debugLog_getLevel)() > 0)
-          || fd_counter == VG_(log_output_sink).fd
-          || fd_counter == VG_(xml_output_sink).fd) {
-         /* Split the range if it contains a file descriptor we're not
-          * supposed to close. */
-         if (fd_counter - 1 >= lowfd) {
-            res = VG_(do_syscall3)(__NR_close_range, (UWord)lowfd, (UWord)fd_counter - 1, ARG3 );
-         }
-         lowfd = fd_counter + 1;
-      }
-   } while (fd_counter++ <= highfd);
+   vg_assert(VG_(log_output_sink).fd == -1 ||
+             VG_(log_output_sink).fd >= VG_(fd_hard_limit));
+   vg_assert(VG_(xml_output_sink).fd == -1 ||
+             VG_(xml_output_sink).fd >= VG_(fd_hard_limit));
 
-   /* If it failed along the way, it's presumably the flags being wrong. */
-   SET_STATUS_from_SysRes (res);
+   if (VG_(debugLog_getLevel)() > 0 &&
+      lowfd <= 2U &&
+      highfd >= 2U &&
+      lowfd != highfd) {
+      SysRes res = VG_(mk_SysRes_Success)(0);
+      if (lowfd <= 1U) {
+         res = VG_(do_syscall3)(__NR_close_range, lowfd, 1U, ARG3);
+      }
+      if (!sr_isError(res) && highfd >= 3U) {
+         res = VG_(do_syscall3)(__NR_close_range, 3U, highfd, ARG3);
+      }
+      /* If it failed along the way, it's presumably the flags being wrong. */
+      SET_STATUS_from_SysRes (res);
+   } else {
+      SET_STATUS_from_SysRes(VG_(do_syscall3)(__NR_close_range, lowfd, highfd, ARG3));
+   }
 }
 
 POST(sys_close_range)
 {
-   unsigned int fd;
-   unsigned int last = ARG2;
+   UInt fd;
+   UInt highfd = ARG2;
 
    if (!VG_(clo_track_fds)
        || (ARG3 & VKI_CLOSE_RANGE_CLOEXEC) != 0)
       return;
 
-   if (last >= VG_(fd_hard_limit))
-      last = VG_(fd_hard_limit) - 1;
+   if (highfd >= VG_(fd_hard_limit))
+       highfd = VG_(fd_hard_limit) - 1;
 
    /* If the close_range range is too wide, we don't want to loop
       through the whole range.  */
-   if (ARG2 == ~0U)
-     ML_(record_fd_close_range)(tid, ARG1);
-   else {
-      for (fd = ARG1; fd <= last; fd++)
-         if ((fd != 2/*stderr*/ || VG_(debugLog_getLevel)() == 0)
-             && fd != VG_(log_output_sink).fd
-             && fd != VG_(xml_output_sink).fd)
+   if (ARG2 >= VG_(fd_hard_limit)) {
+      ML_(record_fd_close_range)(tid, ARG1);
+   } else {
+      for (fd = ARG1; fd <= highfd; fd++)
+         if ((fd != 2/*stderr*/ || VG_(debugLog_getLevel)() == 0))
             ML_(record_fd_close)(tid, fd);
    }
 }
index 6d8b5a0ba842cfe0fcf44074b659441217484bd7..5c21e7f42b6a7f70aa5100697b4ad7ce6e16c873 100644 (file)
@@ -65,7 +65,7 @@ int main(void)
    
    errno = 0;
    // wrong order
-   close_range(fd3, fd1, 2);
+   close_range(fd3, fd1, 0);
    assert(errno = EINVAL);
    
    errno = 0;
@@ -82,6 +82,9 @@ int main(void)
    
    close_range(3, rl.rlim_cur+1, 0);
    
+   int res = close_range(2U, ~0U, 0);
+   assert(res == 0);
+   
    {
       unsigned a;
       unsigned b;
index 2f4d018f22e1a56c457c75ad21574791b6f2768f..51dfcd40a5f746f3c7373ff531858a57826abccc 100644 (file)
@@ -1,12 +1,12 @@
 Syscall param close_range(lowfd) contains uninitialised byte(s)
    at 0x........: close_range (in /...libc...)
-   by 0x........: main (close_range.c:89)
+   by 0x........: main (close_range.c:92)
 
 Syscall param close_range(highfd) contains uninitialised byte(s)
    at 0x........: close_range (in /...libc...)
-   by 0x........: main (close_range.c:89)
+   by 0x........: main (close_range.c:92)
 
 Syscall param close_range(flags) contains uninitialised byte(s)
    at 0x........: close_range (in /...libc...)
-   by 0x........: main (close_range.c:89)
+   by 0x........: main (close_range.c:92)