From: Martin Cermak Date: Fri, 27 Jun 2025 20:36:03 +0000 (+0200) Subject: Wrap linux specific syscalls 457 (listmount) and 458 (statmount) X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=refs%2Fheads%2Fmaster;p=thirdparty%2Fvalgrind.git Wrap linux specific syscalls 457 (listmount) and 458 (statmount) 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 --- diff --git a/NEWS b/NEWS index 0d9cc798e..c1940b56c 100644 --- 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 diff --git a/coregrind/m_syswrap/priv_syswrap-linux.h b/coregrind/m_syswrap/priv_syswrap-linux.h index ed8cb4ed5..9e6cb8981 100644 --- a/coregrind/m_syswrap/priv_syswrap-linux.h +++ b/coregrind/m_syswrap/priv_syswrap-linux.h @@ -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); diff --git a/coregrind/m_syswrap/syswrap-amd64-linux.c b/coregrind/m_syswrap/syswrap-amd64-linux.c index 292e969fc..22989f9fa 100644 --- a/coregrind/m_syswrap/syswrap-amd64-linux.c +++ b/coregrind/m_syswrap/syswrap-amd64-linux.c @@ -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 }; diff --git a/coregrind/m_syswrap/syswrap-arm-linux.c b/coregrind/m_syswrap/syswrap-arm-linux.c index 6d7db0425..7bd69b681 100644 --- a/coregrind/m_syswrap/syswrap-arm-linux.c +++ b/coregrind/m_syswrap/syswrap-arm-linux.c @@ -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 }; diff --git a/coregrind/m_syswrap/syswrap-arm64-linux.c b/coregrind/m_syswrap/syswrap-arm64-linux.c index 2d6b45f91..40eb65432 100644 --- a/coregrind/m_syswrap/syswrap-arm64-linux.c +++ b/coregrind/m_syswrap/syswrap-arm64-linux.c @@ -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 }; diff --git a/coregrind/m_syswrap/syswrap-linux.c b/coregrind/m_syswrap/syswrap-linux.c index 0db871778..97d386290 100644 --- a/coregrind/m_syswrap/syswrap-linux.c +++ b/coregrind/m_syswrap/syswrap-linux.c @@ -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; diff --git a/coregrind/m_syswrap/syswrap-mips32-linux.c b/coregrind/m_syswrap/syswrap-mips32-linux.c index 5edae82c3..734f129c8 100644 --- a/coregrind/m_syswrap/syswrap-mips32-linux.c +++ b/coregrind/m_syswrap/syswrap-mips32-linux.c @@ -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 }; diff --git a/coregrind/m_syswrap/syswrap-mips64-linux.c b/coregrind/m_syswrap/syswrap-mips64-linux.c index 63e4b111e..67e5c0b37 100644 --- a/coregrind/m_syswrap/syswrap-mips64-linux.c +++ b/coregrind/m_syswrap/syswrap-mips64-linux.c @@ -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), }; diff --git a/coregrind/m_syswrap/syswrap-nanomips-linux.c b/coregrind/m_syswrap/syswrap-nanomips-linux.c index b392ad1ad..a4da2be9b 100644 --- a/coregrind/m_syswrap/syswrap-nanomips-linux.c +++ b/coregrind/m_syswrap/syswrap-nanomips-linux.c @@ -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), }; diff --git a/coregrind/m_syswrap/syswrap-ppc32-linux.c b/coregrind/m_syswrap/syswrap-ppc32-linux.c index 9d02a0258..b5d45e109 100644 --- a/coregrind/m_syswrap/syswrap-ppc32-linux.c +++ b/coregrind/m_syswrap/syswrap-ppc32-linux.c @@ -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 }; diff --git a/coregrind/m_syswrap/syswrap-ppc64-linux.c b/coregrind/m_syswrap/syswrap-ppc64-linux.c index 94385a4fa..764fb557e 100644 --- a/coregrind/m_syswrap/syswrap-ppc64-linux.c +++ b/coregrind/m_syswrap/syswrap-ppc64-linux.c @@ -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 }; diff --git a/coregrind/m_syswrap/syswrap-riscv64-linux.c b/coregrind/m_syswrap/syswrap-riscv64-linux.c index 68ccd0ea4..d572672f8 100644 --- a/coregrind/m_syswrap/syswrap-riscv64-linux.c +++ b/coregrind/m_syswrap/syswrap-riscv64-linux.c @@ -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 */ }; diff --git a/coregrind/m_syswrap/syswrap-s390x-linux.c b/coregrind/m_syswrap/syswrap-s390x-linux.c index a6770399d..8202c1922 100644 --- a/coregrind/m_syswrap/syswrap-s390x-linux.c +++ b/coregrind/m_syswrap/syswrap-s390x-linux.c @@ -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 }; diff --git a/coregrind/m_syswrap/syswrap-x86-linux.c b/coregrind/m_syswrap/syswrap-x86-linux.c index 4b5b5fb15..45216b45f 100644 --- a/coregrind/m_syswrap/syswrap-x86-linux.c +++ b/coregrind/m_syswrap/syswrap-x86-linux.c @@ -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 }; diff --git a/include/vki/vki-linux.h b/include/vki/vki-linux.h index 0d2bed6dc..65406fffe 100644 --- a/include/vki/vki-linux.h +++ b/include/vki/vki-linux.h @@ -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 ---*/ /*--------------------------------------------------------------------*/ diff --git a/include/vki/vki-scnums-shared-linux.h b/include/vki/vki-scnums-shared-linux.h index 32ef8ac13..9c20964c5 100644 --- a/include/vki/vki-scnums-shared-linux.h +++ b/include/vki/vki-scnums-shared-linux.h @@ -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