]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Wrap linux specific syscalls 457 (listmount) and 458 (statmount)
authorMartin Cermak <mcermak@redhat.com>
Fri, 27 Jun 2025 20:36:03 +0000 (22:36 +0200)
committerMark Wielaard <mark@klomp.org>
Fri, 27 Jun 2025 20:52:01 +0000 (22:52 +0200)
The listmount syscall returns a list of mount IDs under the req.mnt_id.
This is meant to be used in conjunction with statmount(2) in order to
provide a way to iterate and discover mounted file systems.

The statmount syscall returns information about a mount, storing it in
the buffer pointed to by smbuf.  The returned buffer is a struct
statmount which is of size bufsize.

Declare a sys_{lis,sta}tmount wrapper in priv_syswrap-linux.h and hook it
for {amd64,arm,arm64,mips64,nanomips,ppc32,ppc64,riscv64,s390x,x86}-linux
using LINXY with PRE and POST handler in syswrap-linux.c

Both syscalls need CAP_SYS_ADMIN, to successfully test.

Resolves: https://bugs.kde.org/show_bug.cgi?id=502968

16 files changed:
NEWS
coregrind/m_syswrap/priv_syswrap-linux.h
coregrind/m_syswrap/syswrap-amd64-linux.c
coregrind/m_syswrap/syswrap-arm-linux.c
coregrind/m_syswrap/syswrap-arm64-linux.c
coregrind/m_syswrap/syswrap-linux.c
coregrind/m_syswrap/syswrap-mips32-linux.c
coregrind/m_syswrap/syswrap-mips64-linux.c
coregrind/m_syswrap/syswrap-nanomips-linux.c
coregrind/m_syswrap/syswrap-ppc32-linux.c
coregrind/m_syswrap/syswrap-ppc64-linux.c
coregrind/m_syswrap/syswrap-riscv64-linux.c
coregrind/m_syswrap/syswrap-s390x-linux.c
coregrind/m_syswrap/syswrap-x86-linux.c
include/vki/vki-linux.h
include/vki/vki-scnums-shared-linux.h

diff --git a/NEWS b/NEWS
index 0d9cc798ec8b819319aab0875e696f6d72a4bb07..c1940b56ced8021c92441edf4b4cf6f982595e21 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -44,6 +44,7 @@ are not entered into bugzilla tend to get forgotten about or ignored.
 504936  Add FreeBSD amd64 sysarch subcommands AMD64_SET_TLSBASE and
         AMD64_GET_TLSBASE
 505228  Wrap linux specific mseal syscall
+502968  Wrap linux specific syscalls 457 (listmount) and 458 (statmount)
 
 To see details of a given bug, visit
   https://bugs.kde.org/show_bug.cgi?id=XXXXXX
index ed8cb4ed50ed4ee2aa1a2e332bdac7d8a1679911..9e6cb89811a8a8ca9aa3bf7b9424c11a49c206f0 100644 (file)
@@ -355,6 +355,10 @@ DECL_TEMPLATE(linux, sys_pidfd_getfd);
 // Since Linux 6.6
 DECL_TEMPLATE(linux, sys_fchmodat2);
 
+// Since Linux 6.8
+DECL_TEMPLATE(linux, sys_listmount);
+DECL_TEMPLATE(linux, sys_statmount);
+
 // Since Linux 6.10
 DECL_TEMPLATE(linux, sys_mseal);
 
index 292e969fc1c8837dd6dbec4fa7a6827029517f81..22989f9fa56bb86bba30531f0f466497e5694f7d 100644 (file)
@@ -904,6 +904,8 @@ static SyscallTableEntry syscall_table[] = {
 
    LINXY(__NR_cachestat,         sys_cachestat),         // 451
    LINX_(__NR_fchmodat2,         sys_fchmodat2),         // 452
+   LINXY(__NR_statmount,         sys_statmount),         // 457
+   LINXY(__NR_listmount,         sys_listmount),         // 458
    LINX_(__NR_mseal,             sys_mseal),             // 462
 };
 
index 6d7db0425bdafa25cc1aad27a2c6b27e926970c3..7bd69b6817a2c98bc589ed61b79842068bac600c 100644 (file)
@@ -1075,6 +1075,8 @@ static SyscallTableEntry syscall_main_table[] = {
 
    LINXY(__NR_cachestat,         sys_cachestat),         // 451
    LINX_(__NR_fchmodat2,         sys_fchmodat2),         // 452
+   LINXY(__NR_statmount,         sys_statmount),         // 457
+   LINXY(__NR_listmount,         sys_listmount),         // 458
    LINX_(__NR_mseal,             sys_mseal),             // 462
 };
 
index 2d6b45f91665965fea02a3d40cb3bf29bc26728d..40eb65432449a88f398daf8033a5fc1f911712c2 100644 (file)
@@ -855,6 +855,8 @@ static SyscallTableEntry syscall_main_table[] = {
 
    LINXY(__NR_cachestat,         sys_cachestat),         // 451
    LINX_(__NR_fchmodat2,         sys_fchmodat2),         // 452
+   LINXY(__NR_statmount,         sys_statmount),         // 457
+   LINXY(__NR_listmount,         sys_listmount),         // 458
    LINX_(__NR_mseal,             sys_mseal),             // 462
 };
 
index 0db8717786d4d1c73c4bc2493b730ad8ee8a8e93..97d386290201e30117b0ea87f95c236385029835 100644 (file)
@@ -4305,6 +4305,59 @@ PRE(sys_mseal)
        SET_STATUS_Failure(VKI_ENOMEM);
 }
 
+PRE(sys_statmount)
+{
+   // int syscall(SYS_statmount, struct mnt_id_req *req,
+   //             struct statmount *smbuf, size_t bufsize,
+   //             unsigned long flags);
+   FUSE_COMPATIBLE_MAY_BLOCK();
+   PRINT("sys_statmount ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %lu,  %#" FMT_REGWORD "x)", ARG1, ARG2, ARG3, ARG4);
+   PRE_REG_READ4(long, "statmount", struct vki_mnt_id_req *, req, struct vki_statmount *, smbuf, vki_size_t, bufsize, unsigned long, flags);
+
+   struct vki_mnt_id_req *req = (struct vki_mnt_id_req *)(Addr)ARG1;
+   if (!ML_(safe_to_deref) ((void *)&req->size, sizeof(vki_size_t)))
+      PRE_MEM_READ("statmount(req)", ARG1, sizeof(struct vki_mnt_id_req));
+   else
+      PRE_MEM_READ("statmount(req)", ARG1, req->size);
+
+   struct vki_statmount *smbuf = (struct vki_statmount *)(Addr)ARG2;
+   if (!ML_(safe_to_deref) ((void *)&smbuf->size, sizeof(struct vki_statmount)))
+      PRE_MEM_WRITE("statmount(smbuf)", ARG2, sizeof(struct vki_statmount));
+   else
+     PRE_MEM_WRITE("statmount(smbuf)", ARG2, ARG3);
+}
+
+POST(sys_statmount)
+{
+   struct vki_statmount *smbuf = (struct vki_statmount *)(Addr)ARG2;
+   POST_MEM_WRITE((Addr)smbuf, smbuf->size);
+}
+
+PRE(sys_listmount)
+{
+   // int syscall(SYS_listmount, struct mnt_id_req *req,
+   //             uint64_t *mnt_ids, size_t nr_mnt_ids,
+   //             unsigned long flags);
+   FUSE_COMPATIBLE_MAY_BLOCK();
+   PRINT("sys_listmount ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %lu,  %#" FMT_REGWORD "x)", ARG1, ARG2, ARG3, ARG4);
+   PRE_REG_READ4(long, "listmount", struct vki_mnt_id_req *, req, vki_uint64_t *, mnt_ids, vki_size_t, nr_mnt_ids, unsigned long, flags);
+
+   struct vki_mnt_id_req *req = (struct vki_mnt_id_req *)(Addr)ARG1;
+   if (!ML_(safe_to_deref) ((void *)&req->size, sizeof(vki_size_t)))
+      PRE_MEM_READ("listmount(req)", ARG1, sizeof(struct vki_mnt_id_req));
+   else
+      PRE_MEM_READ("listmount(req)", ARG1, req->size);
+
+   PRE_MEM_WRITE("listmount(mnt_ids)", ARG2, ARG3 * sizeof(vki_uint64_t));
+}
+
+POST(sys_listmount)
+{
+   if (RES > 0) {
+      POST_MEM_WRITE(ARG2, RES * sizeof(vki_uint64_t));
+   }
+}
+
 PRE(sys_syncfs)
 {
    *flags |= SfMayBlock;
index 5edae82c31f183cf8fe005dacf4fec9d9c212121..734f129c87f33a1cb9328a48e692a7db31eb610c 100644 (file)
@@ -1182,6 +1182,8 @@ static SyscallTableEntry syscall_main_table[] = {
 
    LINXY(__NR_cachestat,               sys_cachestat),               // 451
    LINX_(__NR_fchmodat2,               sys_fchmodat2),               // 452
+   LINX_(__NR_statmount,               sys_statmount),               // 457
+   LINX_(__NR_listmount,               sys_listmount),               // 458
    LINX_(__NR_mseal,                   sys_mseal),                   // 462
 };
 
index 63e4b111ec56cd422f1238655b0298ae00e319ad..67e5c0b37db7f05ba29e7ed5c0339f1dac450222 100644 (file)
@@ -838,6 +838,8 @@ static SyscallTableEntry syscall_main_table[] = {
    LINXY (__NR_cachestat, sys_cachestat),
    LINX_ (__NR_fchmodat2, sys_fchmodat2),
    LINXY (__NR_userfaultfd, sys_userfaultfd),
+   LINXY (__NR_statmount, sys_statmount),
+   LINXY (__NR_listmount, sys_listmount),
    LINX_ (__NR_mseal, sys_mseal),
 };
 
index b392ad1adea8e08ffaadc0cb4d5e3cde926cffa0..a4da2be9ba251288849c368132695f6f871fefad 100644 (file)
@@ -842,6 +842,8 @@ static SyscallTableEntry syscall_main_table[] = {
    LINX_ (__NR_landlock_restrict_self, sys_landlock_restrict_self),
    LINXY (__NR_cachestat,              sys_cachestat),
    LINX_ (__NR_fchmodat2,              sys_fchmodat2),
+   LINXY (__NR_statmount,              sys_statmount),
+   LINXY (__NR_listmount,              sys_listmount),
    LINX_ (__NR_mseal,                  sys_mseal),
 };
 
index 9d02a02580689c57ef4ea00c3b24811064e49db0..b5d45e10940ba86890775ed4834aada58b775b81 100644 (file)
@@ -1081,6 +1081,8 @@ static SyscallTableEntry syscall_table[] = {
 
    LINXY(__NR_cachestat,         sys_cachestat),         // 451
    LINX_ (__NR_fchmodat2,        sys_fchmodat2),         // 452
+   LINXY (__NR_statmount,        sys_statmount),         // 457
+   LINXY (__NR_listmount,        sys_listmount),         // 458
    LINX_ (__NR_mseal,            sys_mseal),             // 462
 };
 
index 94385a4fa11764ee02830ff0a988d893de729d8e..764fb557ec67d54e23fb4c5203e910752df5de80 100644 (file)
@@ -1048,6 +1048,8 @@ static SyscallTableEntry syscall_table[] = {
 
    LINXY (__NR_cachestat,        sys_cachestat),         // 451
    LINX_ (__NR_fchmodat2,        sys_fchmodat2),         // 452
+   LINXY (__NR_statmount,        sys_statmount),         // 457
+   LINXY (__NR_listmount,        sys_listmount),         // 458
    LINX_ (__NR_mseal,            sys_mseal),             // 462
 };
 
index 68ccd0ea49032bc16c17774cb2a110cec827023d..d572672f85d327fb4272e89d9d38834232ec9c85 100644 (file)
@@ -599,6 +599,8 @@ static SyscallTableEntry syscall_main_table[] = {
    LINXY(__NR_memfd_secret, sys_memfd_secret),                     /* 447 */
    LINXY(__NR_cachestat, sys_cachestat),                           /* 451 */
    LINX_(__NR_fchmodat2, sys_fchmodat2),                           /* 452 */
+   LINXY(__NR_statmount, sys_statmount),                           /* 457 */
+   LINXY(__NR_listmount, sys_listmount),                           /* 458 */
    LINX_(__NR_mseal, sys_mseal),                                   /* 462 */
 };
 
index a6770399dd33afc04ea0dd0f09a3292fa6d348cb..8202c1922d1eddaf5df1df825ff8aaf3e09434a9 100644 (file)
@@ -890,6 +890,8 @@ static SyscallTableEntry syscall_table[] = {
 
    LINXY (__NR_cachestat, sys_cachestat),                             // 451
    LINX_ (__NR_fchmodat2, sys_fchmodat2),                             // 452
+   LINXY (__NR_statmount, sys_statmount),                             // 457
+   LINXY (__NR_listmount, sys_listmount),                             // 458
    LINX_ (__NR_mseal, sys_mseal),                                     // 462
 };
 
index 4b5b5fb15f2bafc4044bbaa2f1f2298f792bd6a0..45216b45f4f97d0e444eef37f74ec624d6ee0783 100644 (file)
@@ -1676,6 +1676,8 @@ static SyscallTableEntry syscall_table[] = {
 
    LINXY(__NR_cachestat,         sys_cachestat),         // 451
    LINX_(__NR_fchmodat2,         sys_fchmodat2),         // 452
+   LINXY(__NR_statmount,         sys_statmount),         // 457
+   LINXY(__NR_listmount,         sys_listmount),         // 458
    LINX_(__NR_mseal,             sys_mseal),             // 462
 };
 
index 0d2bed6dc6ae719b33271d7cd44d96f62cd039d8..65406fffe92ba660894c4b9d5414decad6d10dee 100644 (file)
@@ -5502,6 +5502,43 @@ struct vki__aio_sigset {
    vki_size_t          sigsetsize;
 };
 
+//----------------------------------------------------------------------
+// From uapi/linux/mount.h
+//----------------------------------------------------------------------
+
+struct vki_mnt_id_req {
+   __vki_u32 size;
+   __vki_u32 spare;
+   __vki_u64 mnt_id;
+   __vki_u64 param;
+   __vki_u64 mnt_ns_id;
+};
+
+struct vki_statmount {
+       __vki_u32 size;         /* Total size, including strings */
+       __vki_u32 mnt_opts;             /* [str] Mount options of the mount */
+       __vki_u64 mask;         /* What results were written */
+       __vki_u32 sb_dev_major; /* Device ID */
+       __vki_u32 sb_dev_minor;
+       __vki_u64 sb_magic;             /* ..._SUPER_MAGIC */
+       __vki_u32 sb_flags;             /* SB_{RDONLY,SYNCHRONOUS,DIRSYNC,LAZYTIME} */
+       __vki_u32 fs_type;              /* [str] Filesystem type */
+       __vki_u64 mnt_id;               /* Unique ID of mount */
+       __vki_u64 mnt_parent_id;        /* Unique ID of parent (for root == mnt_id) */
+       __vki_u32 mnt_id_old;   /* Reused IDs used in proc/.../mountinfo */
+       __vki_u32 mnt_parent_id_old;
+       __vki_u64 mnt_attr;             /* MOUNT_ATTR_... */
+       __vki_u64 mnt_propagation;      /* MS_{SHARED,SLAVE,PRIVATE,UNBINDABLE} */
+       __vki_u64 mnt_peer_group;       /* ID of shared peer group */
+       __vki_u64 mnt_master;   /* Mount receives propagation from this ID */
+       __vki_u64 propagate_from;       /* Propagation from in current namespace */
+       __vki_u32 mnt_root;             /* [str] Root of mount relative to root of fs */
+       __vki_u32 mnt_point;    /* [str] Mountpoint relative to current root */
+       __vki_u64 mnt_ns_id;    /* ID of the mount namespace */
+       __vki_u64 __spare2[49];
+       char str[];             /* Variable size part containing strings */
+};
+
 /*--------------------------------------------------------------------*/
 /*--- end                                                          ---*/
 /*--------------------------------------------------------------------*/
index 32ef8ac133c9894b8e62446abac27c797de478e7..9c20964c515145c11957e41ca0af7e02c6e82e29 100644 (file)
@@ -56,6 +56,8 @@
 
 #define __NR_cachestat         451
 #define __NR_fchmodat2         452
+#define __NR_statmount         457
+#define __NR_listmount         458
 #define __NR_mseal             462
 
 #endif