]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Bug 504265 - FreeBSD: missing syscall wrappers for fchroot and setcred
authorPaul Floyd <pjfloyd@wanadoo.fr>
Fri, 16 May 2025 05:58:02 +0000 (07:58 +0200)
committerPaul Floyd <pjfloyd@wanadoo.fr>
Fri, 16 May 2025 05:58:02 +0000 (07:58 +0200)
16 files changed:
.gitignore
NEWS
configure.ac
coregrind/m_syswrap/priv_syswrap-freebsd.h
coregrind/m_syswrap/syswrap-freebsd.c
include/vki/vki-freebsd.h
include/vki/vki-scnums-freebsd.h
memcheck/tests/freebsd/Makefile.am
memcheck/tests/freebsd/fchroot.cpp [new file with mode: 0644]
memcheck/tests/freebsd/fchroot.stderr.exp [new file with mode: 0644]
memcheck/tests/freebsd/fchroot.vgtest [new file with mode: 0644]
memcheck/tests/freebsd/scalar.c
memcheck/tests/freebsd/scalar.stderr.exp
memcheck/tests/freebsd/setcred.cpp [new file with mode: 0644]
memcheck/tests/freebsd/setcred.stderr.exp [new file with mode: 0644]
memcheck/tests/freebsd/setcred.vgtest [new file with mode: 0644]

index 962c97606baca34a05e0c48810b226b86f2bbd06..be8c1a2687b32fc5395901953cb71c2ee9fd4edb 100644 (file)
 /memcheck/tests/freebsd/eventfd2
 /memcheck/tests/freebsd/extattr
 /memcheck/tests/freebsd/fbsd278566
+/memcheck/tests/freebsd/fchroot
 /memcheck/tests/freebsd/fexecve
 /memcheck/tests/freebsd/file_locking_wait6
 /memcheck/tests/freebsd/get_set_context
 /memcheck/tests/freebsd/scalar_vfork
 /memcheck/tests/freebsd/sctp
 /memcheck/tests/freebsd/sctp2
+/memcheck/tests/freebsd/setcred
 /memcheck/tests/freebsd/setproctitle
 /memcheck/tests/freebsd/sigwait
 /memcheck/tests/freebsd/stat
diff --git a/NEWS b/NEWS
index a1a5fa24d381a4b142af3adbeb77a639a19dd4ce..bae5f6fcffeb2b7df9a7f79728e0154acadf032a 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -31,6 +31,7 @@ are not entered into bugzilla tend to get forgotten about or ignored.
 504101  Add a "vgstack" script
 504177  FILE DESCRIPTORS banner shows when closing some inherited fds
 501741  syscall cachestat not wrapped
+504265  FreeBSD: missing syscall wrappers for fchroot and setcred
 
 To see details of a given bug, visit
   https://bugs.kde.org/show_bug.cgi?id=XXXXXX
index 00cf62d47cca9b7836753d040d73819a44559f7d..caa79c0147cb9211bb4484df061f18012e45ac61 100755 (executable)
@@ -5006,7 +5006,9 @@ AC_CHECK_FUNCS([     \
         fdatasync    \
         getrandom    \
         getrlimitusage \
-        timer_delete
+        timer_delete \
+        fchroot      \
+        setcred
         ])
 
 # AC_CHECK_LIB adds any library found to the variable LIBS, and links these
@@ -5064,6 +5066,10 @@ AM_CONDITIONAL([HAVE_GETRLIMITUSAGE],
                [test x$ac_cv_func_getrlimitusage = xyes])
 AM_CONDITIONAL([HAVE_TIMER_DELETE],
                [test x$ac_cv_func_timer_delete = xyes])
+AM_CONDITIONAL([HAVE_FCHROOT],
+               [test x$ac_cv_func_fchroot = xyes])
+AM_CONDITIONAL([HAVE_SETCRED],
+               [test x$ac_cv_func_setcred = xyes])
 
 if test x$VGCONF_PLATFORM_PRI_CAPS = xMIPS32_LINUX \
      -o x$VGCONF_PLATFORM_PRI_CAPS = xMIPS64_LINUX \
index 8b78c5d742f5bd7ed1b49385d61461a8cfb5bccd..f8d404239d50f90fa3b704486b0a035f6bc6cc00 100644 (file)
@@ -538,7 +538,10 @@ DECL_TEMPLATE(freebsd, sys_timerfd_settime) // 587
 
 // __FreeBSD_version 1400507 and 1500012
 DECL_TEMPLATE(freebsd, sys_kcmp) // 588
+
 DECL_TEMPLATE(freebsd, sys_getrlimitusage) // 589
+DECL_TEMPLATE(freebsd, sys_fchroot) // 590
+DECL_TEMPLATE(freebsd, sys_setcred) // 591
 
 DECL_TEMPLATE(freebsd, sys_fake_sigreturn)
 
index 41cd0756196b292878811e0ace974e31d7a6bec3..8fcfe10904183bc07a556e5218a4e4f08ab7f43f 100644 (file)
@@ -7001,6 +7001,28 @@ POST(sys_getrlimitusage)
    }
 }
 
+// SYS_fchroot 590
+// int fchroot(int fd);
+PRE(sys_fchroot)
+{
+   PRINT("sys_fchroot(%ld)", ARG1);
+   PRE_REG_READ1(int, "fchroot", int, fd);
+
+   /* Be strict. */
+   if (!ML_(fd_allowed)(ARG1, "fchroot", tid, False))
+      SET_STATUS_Failure(VKI_EBADF);
+}
+
+// SYS_setcred
+// int setcred(u_int flags, const struct setcred *wcred, size_t size);
+PRE(sys_setcred)
+{
+   PRINT("sys_setcred(%ld, %#" FMT_REGWORD "x, %lu)", ARG1, ARG2, ARG3);
+   PRE_REG_READ3(int, "setcred", u_int, flags, const struct setcred*, wcred, size_t, size);
+   PRE_MEM_READ("setcred(wcred)", ARG2, sizeof(struct vki_setcred));
+}
+
+
 #undef PRE
 #undef POST
 
@@ -7694,6 +7716,9 @@ const SyscallTableEntry ML_(syscall_table)[] = {
    BSDX_(__NR_kcmp,             sys_kcmp),              // 588
    BSDXY(__NR_getrlimitusage,   sys_getrlimitusage),    // 589
 
+   BSDX_(__NR_fchroot,          sys_fchroot),           // 590
+   BSDX_(__NR_setcred,          sys_setcred),           // 591
+
    BSDX_(__NR_fake_sigreturn,   sys_fake_sigreturn),    // 1000, fake sigreturn
 
 };
index b870025f0fa821d50fc6db78e6c5bd6d1cff280e..25399799952d69de70eb3533f4a1e8146933ac3f 100644 (file)
@@ -3257,6 +3257,23 @@ union vki_ccb {
 
 #define VKI_CAMIOCOMMAND _VKI_IOWR(VKI_CAM_VERSION, 2, union vki_ccb)
 
+//----------------------------------------------------------------------
+// From cam/scsi/scsi_all.h
+//----------------------------------------------------------------------
+struct vki_setcred {
+   vki_uid_t    sc_uid;                /* effective user id */
+   vki_uid_t    sc_ruid;               /* real user id */
+   vki_uid_t    sc_svuid;              /* saved user id */
+   vki_gid_t    sc_gid;                /* effective group id */
+   vki_gid_t    sc_rgid;               /* real group id */
+   vki_gid_t    sc_svgid;              /* saved group id */
+   vki_u_int    sc_pad;                /* see 32-bit compat structure */
+   vki_u_int    sc_supp_groups_nb;     /* number of supplementary groups */
+   vki_gid_t   *sc_supp_groups;        /* supplementary groups */
+   struct vki_mac *sc_label;           /* MAC label */
+};
+
+
 
 /*--------------------------------------------------------------------*/
 /*--- end                                                          ---*/
index 098b722f485c98ade7a31aeb51a169753156c647..a92abb9a1542e66ea4ab9335c5833495a3600d8d 100644 (file)
 #define __NR_kcmp                588
 
 #define __NR_getrlimitusage      589
+#define __NR_fchroot             590
+#define __NR_setcred             591
 
 #define __NR_fake_sigreturn      1000
 
index b362d6148aff4d8c50faa7559cf893a127b14e2e..091d056785c11587aeb8c3e8f5e5bb45994ecacf 100644 (file)
@@ -53,6 +53,8 @@ EXTRA_DIST = \
        extattr.stderr.exp \
        fbsd278566.vgtest \
        fbsd278566.stderr.exp \
+       fchroot.vgtest \
+       fchroot.stderr.exp \
        fexecve.vgtest \
        fexecve.stderr.exp \
        file_locking_wait6.vgtest \
@@ -109,6 +111,8 @@ EXTRA_DIST = \
        sctp2.vgtest \
        sctp2.stderr.exp \
        sctp2.stdout.exp \
+       setcred.vgtest \
+       setcred.stderr.exp \
        setproctitle.vgtest \
        setproctitle.stderr.exp \
        setproctitle.stdout.exp \
@@ -176,6 +180,11 @@ if HAVE_AIO_READV
 check_PROGRAMS += aiov
 endif
 
+if HAVE_FCHROOT
+check_PROGRAMS += fchroot
+fchroot_SOURCES = fchroot.cpp
+endif
+
 if HAVE_GETRLIMITUSAGE
 check_PROGRAMS += getrlimitusage
 endif
@@ -203,6 +212,12 @@ if FREEBSD_KQUEUEX_SYSCALL
 check_PROGRAMS += kqueuex
 endif
 
+if HAVE_SETCRED
+check_PROGRAMS += setcred
+setcred_SOURCES = setcred.cpp
+setcred_CXXFLAGS = ${AM_CXXFLAGS} @FLAG_W_NO_UNINITIALIZED@
+endif
+
 if FREEBSD_TIMERFD_SYSCALL
 check_PROGRAMS += timerfd
 timerfd_LDFLAGS = -lm
diff --git a/memcheck/tests/freebsd/fchroot.cpp b/memcheck/tests/freebsd/fchroot.cpp
new file mode 100644 (file)
index 0000000..84b7ee7
--- /dev/null
@@ -0,0 +1,17 @@
+#include <unistd.h>
+#include <fcntl.h>
+
+int main()
+{
+   int fd1;
+   int* fd2{new int};
+
+   fd1 = open("..", O_DIRECTORY | O_RDONLY);
+   // will fail unless run as root
+   fchroot(fd1);
+
+   fchroot(*fd2);
+
+   delete fd2;
+}
+
diff --git a/memcheck/tests/freebsd/fchroot.stderr.exp b/memcheck/tests/freebsd/fchroot.stderr.exp
new file mode 100644 (file)
index 0000000..938d347
--- /dev/null
@@ -0,0 +1,4 @@
+Syscall param fchroot(fd) contains uninitialised byte(s)
+   at 0x........: fchroot (in /...libc...)
+   by 0x........: main (fchroot.cpp:13)
+
diff --git a/memcheck/tests/freebsd/fchroot.vgtest b/memcheck/tests/freebsd/fchroot.vgtest
new file mode 100644 (file)
index 0000000..a07103e
--- /dev/null
@@ -0,0 +1,3 @@
+prereq: test -e ./fchroot
+prog: fchroot
+vgopts: -q
index 65348c232a1af358b869b7435ea9ccc9983ccc0e..eddde2f428c2c625d66750e74aa84f7c5cf2f717 100644 (file)
@@ -2450,7 +2450,37 @@ int main(void)
    FAKE_SY("   ...\n");
    FAKE_SY(" Address 0x........ is not stack'd, malloc'd or (recently) free'd\n");
    FAKE_SY("\n");
-#endif 
+#endif
+
+#if defined(SYS_fchroot)
+   GO(SYS_fchroot, "1s, 0m");
+   SY(SYS_fchroot, x0+1000);
+#else
+   FAKE_GO("590:             SYS_fchroot 1s, 0m");
+   FAKE_SY("Syscall param fchroot(fd) contains uninitialised byte(s)\n");
+   FAKE_SY("   ...\n");
+   FAKE_SY("\n");
+#endif
+
+#if defined(SYS_setcred)
+   GO(SYS_setcred, "3s, 1m");
+   SY(SYS_setcred, x0+100, x0+3, x0+50);
+#else
+   FAKE_GO("591:             SYS_setcred 3s, 1m");
+   FAKE_SY("Syscall param setcred(flags) contains uninitialised byte(s)\n");
+   FAKE_SY("   ...\n");
+   FAKE_SY("\n");
+   FAKE_SY("Syscall param setcred(wcred) contains uninitialised byte(s)\n");
+   FAKE_SY("   ...\n");
+   FAKE_SY("\n");
+   FAKE_SY("Syscall param setcred(size) contains uninitialised byte(s)\n");
+   FAKE_SY("   ...\n");
+   FAKE_SY("\n");
+   FAKE_SY("Syscall param setcred(wcred) points to unaddressable byte(s)\n");
+   FAKE_SY("   ...\n");
+   FAKE_SY(" Address 0x........ is not stack'd, malloc'd or (recently) free'd\n");
+   FAKE_SY("\n");
+#endif
 
    /* SYS_exit                    1 */
    GO(SYS_exit, "1s 0m");
index 0e47fe1aacd94afd3ad3b082b99d970a1e5c1d7d..59ed18524266ec4f87e91d76258c94cad44fdc7d 100644 (file)
@@ -5740,6 +5740,28 @@ Syscall param getrlimitusage(res) points to unaddressable byte(s)
    ...
  Address 0x........ is not stack'd, malloc'd or (recently) free'd
 
+---------------------------------------------------------
+590:             SYS_fchroot 1s, 0m
+---------------------------------------------------------
+Syscall param fchroot(fd) contains uninitialised byte(s)
+   ...
+
+---------------------------------------------------------
+591:             SYS_setcred 3s, 1m
+---------------------------------------------------------
+Syscall param setcred(flags) contains uninitialised byte(s)
+   ...
+
+Syscall param setcred(wcred) contains uninitialised byte(s)
+   ...
+
+Syscall param setcred(size) contains uninitialised byte(s)
+   ...
+
+Syscall param setcred(wcred) points to unaddressable byte(s)
+   ...
+ Address 0x........ is not stack'd, malloc'd or (recently) free'd
+
 ---------------------------------------------------------
   1:                SYS_exit 1s 0m
 ---------------------------------------------------------
diff --git a/memcheck/tests/freebsd/setcred.cpp b/memcheck/tests/freebsd/setcred.cpp
new file mode 100644 (file)
index 0000000..7553599
--- /dev/null
@@ -0,0 +1,31 @@
+#include <sys/ucred.h>
+#include <cstring>
+
+int main()
+{
+   struct setcred cred1;
+   struct setcred* cred2;
+   int flags1{0};
+   int flags2;
+   size_t size1{sizeof(cred1)};
+   size_t size2;
+
+   std::memset(&cred1, 250, sizeof(cred1));
+
+   // needs to be root to work correctly
+   setcred(flags1, &cred1, size1);
+
+   // not accessible
+   setcred(flags1, nullptr, size1);
+
+   // uninit
+   setcred(flags2, cred2, size2);
+
+   cred2 = new struct setcred;
+
+   // uninit memory
+   setcred(flags1, cred2, size1);
+
+   delete cred2;
+}
+
diff --git a/memcheck/tests/freebsd/setcred.stderr.exp b/memcheck/tests/freebsd/setcred.stderr.exp
new file mode 100644 (file)
index 0000000..1d9cecf
--- /dev/null
@@ -0,0 +1,30 @@
+Syscall param setcred(wcred) points to unaddressable byte(s)
+   at 0x........: setcred (in /...libc...)
+   by 0x........: main (setcred.cpp:19)
+ Address 0x........ is not stack'd, malloc'd or (recently) free'd
+
+Syscall param setcred(flags) contains uninitialised byte(s)
+   at 0x........: setcred (in /...libc...)
+   by 0x........: main (setcred.cpp:22)
+
+Syscall param setcred(wcred) contains uninitialised byte(s)
+   at 0x........: setcred (in /...libc...)
+   by 0x........: main (setcred.cpp:22)
+
+Syscall param setcred(size) contains uninitialised byte(s)
+   at 0x........: setcred (in /...libc...)
+   by 0x........: main (setcred.cpp:22)
+
+Syscall param setcred(wcred) points to uninitialised byte(s)
+   at 0x........: setcred (in /...libc...)
+   by 0x........: main (setcred.cpp:22)
+ Address 0x........ is on thread 1's stack
+ in frame #2, created by __libc_start1 (???:)
+
+Syscall param setcred(wcred) points to uninitialised byte(s)
+   at 0x........: setcred (in /...libc...)
+   by 0x........: main (setcred.cpp:27)
+ Address 0x........ is 0 bytes inside a block of size 48 alloc'd
+   at 0x........: ...operator new... (vg_replace_malloc.c:...)
+   by 0x........: main (setcred.cpp:24)
+
diff --git a/memcheck/tests/freebsd/setcred.vgtest b/memcheck/tests/freebsd/setcred.vgtest
new file mode 100644 (file)
index 0000000..8c4f4d3
--- /dev/null
@@ -0,0 +1,3 @@
+prereq: test -e ./setcred
+prog: setcred
+vgopts: -q