]> sourceware.org Git - valgrind.git/commitdiff
FreeBSD: add syscall wrapper for close_range
authorPaul Floyd <pjfloyd@wanadoo.fr>
Fri, 8 Sep 2023 21:40:12 +0000 (23:40 +0200)
committerPaul Floyd <pjfloyd@wanadoo.fr>
Fri, 8 Sep 2023 21:40:12 +0000 (23:40 +0200)
.gitignore
NEWS
coregrind/m_syswrap/priv_syswrap-freebsd.h
coregrind/m_syswrap/syswrap-freebsd.c
include/vki/vki-freebsd.h
memcheck/tests/freebsd/Makefile.am
memcheck/tests/freebsd/close_range.c [new file with mode: 0644]
memcheck/tests/freebsd/close_range.stderr.exp [new file with mode: 0644]
memcheck/tests/freebsd/close_range.vgtest [new file with mode: 0644]
memcheck/tests/freebsd/scalar_13_plus.c
memcheck/tests/freebsd/scalar_13_plus.stderr.exp

index 6aeb41df945a09af24a572fad27389bfa128d14d..48730f21930d0c3a4bfaa65454c7dc11a8deb1fe 100644 (file)
 /memcheck/tests/freebsd/capsicum
 /memcheck/tests/freebsd/chflags
 /memcheck/tests/freebsd/chmod_chown
+/memcheck/tests/freebsd/close_range
 /memcheck/tests/freebsd/delete_sized_mismatch
 /memcheck/tests/freebsd/errno_aligned_allocs
 /memcheck/tests/freebsd/eventfd1
diff --git a/NEWS b/NEWS
index 4459ddd7cf41c11048fae41ea5ad9769c1f76ff3..c3ee77d516aa9c28b2ff22bf42b1b57a68177bc0 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -20,7 +20,8 @@ AMD64/macOS 10.13 and nanoMIPS/Linux.
 
 * ================== PLATFORM CHANGES =================
 
-* support has been added for FreeBSD 14 and FreeBSD 15.
+* Support has been added for FreeBSD 14 and FreeBSD 15.
+* Add support for the FreeBSD close_range system call.
 
 * ==================== TOOL CHANGES ===================
 
index 8822f22f21d2862eed00f10ace619191372a8ffb..844da82a458f43544db17011b2eac0924f31ed16 100644 (file)
@@ -541,7 +541,7 @@ DECL_TEMPLATE(freebsd, sys_sigfastblock) // 573
 DECL_TEMPLATE(freebsd, sys___realpathat) // 574
 #endif
 
-// unimpl __NR_close_range         575
+DECL_TEMPLATE(freebsd, sys_close_range)  // 575
 
 #endif
 
index a9a77c3f45c38b800c6622ec609620ab86a89ed3..4f304091e569e8f45b7b57e7559559a4815b735c 100644 (file)
@@ -6642,7 +6642,7 @@ POST(sys_shm_open2)
    }
 }
 
-// SYS_sigfastblock
+// SYS_sigfastblock 573
 // int sigfastblock(int cmd, void *ptr);
 PRE(sys_sigfastblock)
 {
@@ -6667,6 +6667,75 @@ PRE(sys___realpathat)
    PRE_MEM_WRITE("__realpathat(buf)", (Addr)ARG3, ARG4);
 }
 
+// SYS_sys_close_range   575
+// int close_range(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;
+
+   /* on linux the may lock if futexes are used
+    * there is a lock in the kernel but I assume it's just
+    * a spinlock */
+   PRINT("sys_close_range ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %"
+         FMT_REGWORD "d )", ARG1, ARG2, SARG3);
+   PRE_REG_READ3(int, "close_range",
+                 unsigned int, lowfd, unsigned int, highfd,
+                 int, flags);
+
+   if (lowfd > highfd) {
+      SET_STATUS_Failure( VKI_EINVAL );
+      return;
+   }
+
+   if (highfd >= VG_(fd_hard_limit))
+      highfd = VG_(fd_hard_limit) - 1;
+
+   if (lowfd > highfd) {
+      SET_STATUS_Success ( 0 );
+      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);
+
+   /* If it failed along the way, it's presumably the flags being wrong. */
+   SET_STATUS_from_SysRes (res);
+}
+
+POST(sys_close_range)
+{
+   unsigned int fd;
+   unsigned int last = 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;
+
+   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)
+         ML_(record_fd_close)(fd);
+}
+
 POST(sys___realpathat)
 {
    POST_MEM_WRITE((Addr)ARG3, ARG4);
@@ -7402,7 +7471,7 @@ const SyscallTableEntry ML_(syscall_table)[] = {
    BSDX_(__NR_sigfastblock,     sys_sigfastblock),      // 573
    BSDXY( __NR___realpathat,    sys___realpathat),      // 574
 #endif
-   // unimpl __NR_close_range         575
+   BSDXY(__NR_close_range,      sys_close_range),       // 575
 #endif
 
 #if (FREEBSD_VERS >= FREEBSD_13_0)
index b30b2933eca4dfc470190541b2b4c4ef902f2187..eee094d34014947561ddcda8b4fc187d1346190e 100644 (file)
@@ -1610,6 +1610,7 @@ struct vki_dirent {
 
 #define VKI_RFSPAWN         (1U<<31U)
 
+#define VKI_CLOSE_RANGE_CLOEXEC     (1<<2)
 
 //----------------------------------------------------------------------
 // From sys/msg.h
index d7aae0fbf075dcbf03a564328e0b1f925f3ab71c..f842feb7e0b926eb030920f37cd0159754b9bad5 100644 (file)
@@ -5,50 +5,50 @@ dist_noinst_SCRIPTS = filter_stderr filter_pts dump_stdout filter_sigwait \
        filter_scalar filter_realpathat filter_fstat filter_eventfd2
 
 EXTRA_DIST = \
-       scalar.h \
-       statfs.vgtest \
-       statfs.stderr.exp \
-       pdfork_pdkill.vgtest \
-       pdfork_pdkill.stderr.exp \
-       getfsstat.vgtest \
-       getfsstat.stderr.exp \
-       getfsstat.supp \
-               getfsstat.stderr.exp-x86 \
-       supponlyobj.vgtest \
-       supponlyobj.stderr.exp \
-       supponlyobj.supp \
-       extattr.vgtest \
-       extattr.stderr.exp \
-       sigwait.vgtest \
-       sigwait.stdout.exp \
-       sigwait.stderr.exp \
-               sigwait.stderr.exp-x86 \
+       capsicum.vgtest \
+       capsicum.stderr.exp \
        chflags.vgtest\
        chflags.stderr.exp \
                chflags.stderr.exp-x86 \
+       close_range.vgtest close_range.stderr.exp \
+       extattr.vgtest \
+       extattr.stderr.exp \
        get_set_login.vgtest \
        get_set_login.stderr.exp \
+       getfsstat.vgtest \
+       getfsstat.stderr.exp \
+       getfsstat.supp \
+               getfsstat.stderr.exp-x86 \
+       pdfork_pdkill.vgtest \
+       pdfork_pdkill.stderr.exp \
        revoke.vgtest \
        revoke.stderr.exp \
-       scalar.vgtest \
+       scalar.h scalar.vgtest \
        scalar.stderr.exp \
                scalar.stderr.exp-x86 \
-       capsicum.vgtest \
-       capsicum.stderr.exp \
-       getfh.vgtest \
-       getfh.stderr.exp \
-       linkat.vgtest \
-       linkat.stderr.exp \
-       scalar_fork.vgtest \
-       scalar_fork.stderr.exp \
-       scalar_thr_exit.vgtest \
-       scalar_thr_exit.stderr.exp \
        scalar_abort2.vgtest \
        scalar_abort2.stderr.exp \
+       scalar_fork.vgtest \
+       scalar_fork.stderr.exp \
        scalar_pdfork.vgtest \
        scalar_pdfork.stderr.exp \
+       scalar_thr_exit.vgtest \
+       scalar_thr_exit.stderr.exp \
        scalar_vfork.vgtest \
        scalar_vfork.stderr.exp \
+       sigwait.vgtest \
+       sigwait.stdout.exp \
+       sigwait.stderr.exp \
+               sigwait.stderr.exp-x86 \
+       statfs.vgtest \
+       statfs.stderr.exp \
+       supponlyobj.vgtest \
+       supponlyobj.stderr.exp \
+       supponlyobj.supp \
+       getfh.vgtest \
+       getfh.stderr.exp \
+       linkat.vgtest \
+       linkat.stderr.exp \
        stat.vgtest \
        stat.stderr.exp \
                stat.stderr.exp-x86 \
@@ -116,7 +116,7 @@ EXTRA_DIST = \
        delete_sized_mismatch_xml.stderr.exp
 
 check_PROGRAMS = \
-       statfs pdfork_pdkill getfsstat inlinfo inlinfo_nested.so extattr \
+       close_range statfs pdfork_pdkill getfsstat inlinfo inlinfo_nested.so extattr \
        sigwait chflags get_set_login revoke scalar capsicum getfh \
        linkat scalar_fork scalar_thr_exit scalar_abort2 scalar_pdfork \
        scalar_vfork stat file_locking_wait6 utimens access chmod_chown \
diff --git a/memcheck/tests/freebsd/close_range.c b/memcheck/tests/freebsd/close_range.c
new file mode 100644 (file)
index 0000000..5490c80
--- /dev/null
@@ -0,0 +1,77 @@
+#include <unistd.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/resource.h>
+#include <fcntl.h>
+#include <assert.h>
+
+int main(void)
+{
+   struct rlimit rl;
+   // I'm assuming opens start at 3 and get recycled
+   int fd1 = open("close_range.c", O_RDONLY);
+   int fd2 = open("close_range.vgtest", O_RDONLY);
+   int fd3 = open("close_range.stderr.exp", O_RDONLY);
+   
+   // all open
+   close_range(fd1, fd3, 0);
+   // all closed
+   close_range(fd1, fd3, 0);
+   
+   fd1 = open("close_range.c", O_RDONLY);
+   fd2 = open("close_range.vgtest", O_RDONLY);
+   
+   // 3 and 4 open 5 closed
+   close_range(fd1, fd3, 0);
+   
+   fd1 = open("close_range.c", O_RDONLY);
+   fd3 = open("close_range.stderr.exp", O_RDONLY);
+   
+   // 3 and 5 open 4 closed
+   close_range(fd1, fd3, 0);
+   
+   fd1 = open("close_range.c", O_RDONLY);
+   fd2 = open("close_range.vgtest", O_RDONLY);
+   fd3 = open("close_range.stderr.exp", O_RDONLY);
+   
+   // good flag
+   close_range(fd1, fd3, CLOSE_RANGE_CLOEXEC);
+   close_range(fd1, fd3, 0);
+
+   fd1 = open("close_range.c", O_RDONLY);
+   fd2 = open("close_range.vgtest", O_RDONLY);
+   fd3 = open("close_range.stderr.exp", O_RDONLY);
+   
+   errno = 0;
+   // bad flag
+   close_range(fd1, fd3, 2);
+   assert(errno = EINVAL);
+   
+   errno = 0;
+   // wrong order
+   close_range(fd3, fd1, 2);
+   assert(errno = EINVAL);
+   
+   errno = 0;
+   getrlimit(RLIMIT_NOFILE, &rl);
+   
+   // should do nothing
+   close_range(rl.rlim_cur+100, rl.rlim_cur+200, 0);
+   
+   close_range(3, rl.rlim_cur, 0);
+   
+   fd1 = open("close_range.c", O_RDONLY);
+   fd2 = open("close_range.vgtest", O_RDONLY);
+   fd3 = open("close_range.stderr.exp", O_RDONLY);
+   
+   close_range(3, rl.rlim_cur+1, 0);
+   
+   {
+      unsigned a;
+      unsigned b;
+      int c;
+      close_range(a, b, c);
+   }
+}
+
diff --git a/memcheck/tests/freebsd/close_range.stderr.exp b/memcheck/tests/freebsd/close_range.stderr.exp
new file mode 100644 (file)
index 0000000..a7e9db6
--- /dev/null
@@ -0,0 +1,12 @@
+Syscall param close_range(lowfd) contains uninitialised byte(s)
+   at 0x........: close_range (in /...libc...)
+   by 0x........: main (close_range.c:74)
+
+Syscall param close_range(highfd) contains uninitialised byte(s)
+   at 0x........: close_range (in /...libc...)
+   by 0x........: main (close_range.c:74)
+
+Syscall param close_range(flags) contains uninitialised byte(s)
+   at 0x........: close_range (in /...libc...)
+   by 0x........: main (close_range.c:74)
+
diff --git a/memcheck/tests/freebsd/close_range.vgtest b/memcheck/tests/freebsd/close_range.vgtest
new file mode 100644 (file)
index 0000000..f47fde8
--- /dev/null
@@ -0,0 +1,2 @@
+prog: close_range
+vgopts: -q
index b22152ebb213a3af9fca56da689a3aea9585cfbe..6e58e418fb3a1cc6cf6128d27d769fdc26abbff3 100644 (file)
@@ -16,6 +16,10 @@ int main(void)
    /* SYS___realpathat                   574 */
    GO(SYS___realpathat, " 5s 2m");
    SY(SYS___realpathat, x0+0xffff, x0, x0, x0+100, x0+2); FAIL;
+
+   /* SYS_close_range                    575 */
+   GO(SYS_close_range, "3s 0m");
+   SY(SYS_close_range, x0+5, x0+10, x0); SUCC;
    
    /* SYS___specialfd                    577 */
    GO(SYS___specialfd, "3s 1m");
index 489646810bcfc372080e268e3fe6cf24c3252768..43b904e6f4ebbeafaebe13d498da67f9ac5915ca 100644 (file)
@@ -72,6 +72,18 @@ Syscall param __realpathat(buf) points to unaddressable byte(s)
    ...
  Address 0x........ is not stack'd, malloc'd or (recently) free'd
 
+---------------------------------------------------------
+575:         SYS_close_range 3s 0m
+---------------------------------------------------------
+Syscall param close_range(lowfd) contains uninitialised byte(s)
+   ...
+
+Syscall param close_range(highfd) contains uninitialised byte(s)
+   ...
+
+Syscall param close_range(flags) contains uninitialised byte(s)
+   ...
+
 ---------------------------------------------------------
 577:         SYS___specialfd 3s 1m
 ---------------------------------------------------------
This page took 0.058818 seconds and 5 git commands to generate.