From 0aecd4fe70e1522314866c48b6de20b6ea2f08a3 Mon Sep 17 00:00:00 2001 From: Martin Cermak Date: Fri, 19 Sep 2025 17:25:30 +0200 Subject: [PATCH] Wrap the mount_setattr syscall 442 int syscall(SYS_mount_setattr, int dirfd, const char *pathname, unsigned int flags, struct mount_attr *attr, size_t size); The mount_setattr() system call changes the mount properties of a mount or an entire mount tree. If pathname is a relative pathname, then it is interpreted relative to the directory referred to by the file descriptor dirfd. If dirfd is the special value AT_FDCWD, then pathname is interpreted relative to the current working directory of the calling process. If pathname is the empty string and AT_EMPTY_PATH is specified in flags, then the mount properties of the mount identified by dirfd are changed Declare a mount_setattr wrapper in priv_syswrap-linux.h and hook it for {amd64,arm,arm64,mips64,ppc32,ppc64,riscv64,s390x,x86}-linux using LINX_ with PRE handler in syswrap-linux.c Part of this update also is a fix of the sys_move_mount wrapper. Specifically there was a typo mount_moce vs. move_mount, and also there was a problem in handling VKI_AT_FDCWD special fd value in the check for to_fd and to_pathname. https://bugs.kde.org/show_bug.cgi?id=509566 --- NEWS | 1 + coregrind/m_syswrap/priv_syswrap-linux.h | 3 ++ coregrind/m_syswrap/syswrap-amd64-linux.c | 1 + coregrind/m_syswrap/syswrap-arm-linux.c | 1 + coregrind/m_syswrap/syswrap-arm64-linux.c | 1 + coregrind/m_syswrap/syswrap-linux.c | 34 ++++++++++++--------- coregrind/m_syswrap/syswrap-mips32-linux.c | 1 + coregrind/m_syswrap/syswrap-mips64-linux.c | 1 + coregrind/m_syswrap/syswrap-ppc32-linux.c | 1 + coregrind/m_syswrap/syswrap-ppc64-linux.c | 1 + coregrind/m_syswrap/syswrap-riscv64-linux.c | 1 + coregrind/m_syswrap/syswrap-s390x-linux.c | 1 + coregrind/m_syswrap/syswrap-x86-linux.c | 1 + include/vki/vki-scnums-shared-linux.h | 1 + 14 files changed, 34 insertions(+), 15 deletions(-) diff --git a/NEWS b/NEWS index 66a9f29a2..ecd58cc50 100644 --- a/NEWS +++ b/NEWS @@ -138,6 +138,7 @@ are not entered into bugzilla tend to get forgotten about or ignored. 509139 Update BadSize error messages 509258 FreeBSD: add jail_attach_jd and jail_remove_jd syscall wrappers 509517 s390x: Even/odd lane confusion in various vector insns +509566 Wrap amd64-linux syscall: 442 (mount_setattr) 509590 Run the LTP tests with LTP_QUIET 509567 unhandled amd64-linux syscall: 443 (quotactl_fd) 509642 Add missing ppc64-linux syswraps diff --git a/coregrind/m_syswrap/priv_syswrap-linux.h b/coregrind/m_syswrap/priv_syswrap-linux.h index 752bdf737..53aa1b582 100644 --- a/coregrind/m_syswrap/priv_syswrap-linux.h +++ b/coregrind/m_syswrap/priv_syswrap-linux.h @@ -346,6 +346,9 @@ DECL_TEMPLATE(linux, sys_pidfd_open); DECL_TEMPLATE(linux, sys_close_range); DECL_TEMPLATE(linux, sys_openat2); +// Linux-specific (new in Linux 5.12) +DECL_TEMPLATE(linux, sys_mount_setattr) + // Linux-specific (new in Linux 5.13) DECL_TEMPLATE(linux, sys_landlock_create_ruleset) DECL_TEMPLATE(linux, sys_landlock_add_rule) diff --git a/coregrind/m_syswrap/syswrap-amd64-linux.c b/coregrind/m_syswrap/syswrap-amd64-linux.c index 8b2c95037..4a3bad55f 100644 --- a/coregrind/m_syswrap/syswrap-amd64-linux.c +++ b/coregrind/m_syswrap/syswrap-amd64-linux.c @@ -895,6 +895,7 @@ static SyscallTableEntry syscall_table[] = { LINX_(__NR_faccessat2, sys_faccessat2), // 439 LINXY(__NR_epoll_pwait2, sys_epoll_pwait2), // 441 + LINX_(__NR_mount_setattr, sys_mount_setattr), // 442 LINX_(__NR_quotactl_fd, sys_quotactl_fd), // 443 LINXY(__NR_landlock_create_ruleset, sys_landlock_create_ruleset), // 444 diff --git a/coregrind/m_syswrap/syswrap-arm-linux.c b/coregrind/m_syswrap/syswrap-arm-linux.c index e4f5e4c09..f55ed05e6 100644 --- a/coregrind/m_syswrap/syswrap-arm-linux.c +++ b/coregrind/m_syswrap/syswrap-arm-linux.c @@ -1069,6 +1069,7 @@ static SyscallTableEntry syscall_main_table[] = { LINXY(__NR_pidfd_getfd, sys_pidfd_getfd), // 438 LINX_(__NR_faccessat2, sys_faccessat2), // 439 LINXY(__NR_epoll_pwait2, sys_epoll_pwait2), // 441 + LINX_(__NR_mount_setattr, sys_mount_setattr), // 442 LINX_(__NR_quotactl_fd, sys_quotactl_fd), // 443 LINXY(__NR_landlock_create_ruleset, sys_landlock_create_ruleset), // 444 diff --git a/coregrind/m_syswrap/syswrap-arm64-linux.c b/coregrind/m_syswrap/syswrap-arm64-linux.c index e1a8a883f..b28b4598c 100644 --- a/coregrind/m_syswrap/syswrap-arm64-linux.c +++ b/coregrind/m_syswrap/syswrap-arm64-linux.c @@ -846,6 +846,7 @@ static SyscallTableEntry syscall_main_table[] = { LINX_(__NR_faccessat2, sys_faccessat2), // 439 LINXY(__NR_epoll_pwait2, sys_epoll_pwait2), // 441 + LINX_(__NR_mount_setattr, sys_mount_setattr), // 442 LINX_(__NR_quotactl_fd, sys_quotactl_fd), // 443 LINXY(__NR_landlock_create_ruleset, sys_landlock_create_ruleset), // 444 diff --git a/coregrind/m_syswrap/syswrap-linux.c b/coregrind/m_syswrap/syswrap-linux.c index 547417698..d891ac6da 100644 --- a/coregrind/m_syswrap/syswrap-linux.c +++ b/coregrind/m_syswrap/syswrap-linux.c @@ -1025,6 +1025,18 @@ PRE(sys_mount) PRE_MEM_RASCIIZ( "mount(type)", ARG3); } +PRE(sys_mount_setattr) +{ + // int syscall(SYS_mount_setattr, int dirfd, const char *pathname, + // unsigned int flags, struct mount_attr *attr, size_t size); + *flags |= SfMayBlock; + PRINT("sys_mount_setattr ( %d, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %#" + FMT_REGWORD "x, %" FMT_REGWORD "u )", (Int)ARG1, ARG2, + ARG3, ARG4, ARG5); + PRE_MEM_READ("mount(attr)", ARG5, ARG6); + ML_(fd_at_check_allowed)(SARG1, (const HChar*)ARG2, "mount_setattr(dirfd)", tid, status); +} + PRE(sys_oldumount) { PRINT("sys_oldumount( %#" FMT_REGWORD "x )", ARG1); @@ -2897,9 +2909,9 @@ PRE(sys_fanotify_mark) #else # error Unexpected word size #endif - if ( !ML_(fd_allowed)(SARG1, "fanotify_mark[fanotify_fd]", tid, False) ) + if ( !ML_(fd_allowed)(SARG1, "fanotify_mark(fanotify_fd)", tid, False) ) SET_STATUS_Failure( VKI_EBADF ); - ML_(fd_at_check_allowed)(SARG4, (const HChar*)ARG5, "mkdirat[firfd]", tid, status); + ML_(fd_at_check_allowed)(SARG4, (const HChar*)ARG5, "fanotify_mark(dirfd)", tid, status); } /* --------------------------------------------------------------------- @@ -14340,27 +14352,19 @@ PRE(sys_move_mount) "%ld, %#" FMT_REGWORD "x(%s), %ld", SARG1, ARG2, (HChar*)(Addr)ARG2, SARG3, ARG4, (HChar*)(Addr)ARG4, SARG5); - PRE_REG_READ5(long, "mount_move", + PRE_REG_READ5(long, "move_mount", int, from_dfd, const char *, from_pathname, int, to_dfd, const char*, to_pathname, int, flags); - PRE_MEM_RASCIIZ( "mount_move(from_pathname)", ARG2); + PRE_MEM_RASCIIZ( "move_mount(from_pathname)", ARG2); /* For absolute filenames, from_dfd is ignored. If from_dfd is AT_FDCWD, from_pathname is relative to cwd. When comparing from_dfd against AT_FDCWD, be sure only to compare the bottom 32 bits. */ - if (ML_(safe_to_deref)( (void*)(Addr)ARG2, 1 ) - && *(Char *)(Addr)ARG2 != '/' - && ((Int)ARG1) != ((Int)VKI_AT_FDCWD) - && !ML_(fd_allowed)(ARG1, "mount_move", tid, False)) - SET_STATUS_Failure( VKI_EBADF ); - PRE_MEM_RASCIIZ( "mount_move(from_pathname)", ARG4); + ML_(fd_at_check_allowed)(SARG1, (const HChar*)ARG2, "move_mount(from_dfd)", tid, status); + PRE_MEM_RASCIIZ( "move_mount(to_pathname)", ARG4); /* For absolute filenames, to_dfd is ignored. If to_dfd is AT_FDCWD, to_pathname is relative to cwd. When comparing to_dfd against AT_FDCWD, be sure only to compare the bottom 32 bits. */ - if (ML_(safe_to_deref)( (void*)(Addr)ARG4, 1 ) - && *(Char *)(Addr)ARG4 != '/' - && ((Int)ARG4) != ((Int)VKI_AT_FDCWD) - && !ML_(fd_allowed)(ARG3, "mount_move", tid, False)) - SET_STATUS_Failure( VKI_EBADF ); + ML_(fd_at_check_allowed)(SARG3, (const HChar*)ARG4, "move_mount(to_dfd)", tid, status); } /* int fsopen (const char *fs_name, unsigned int flags) */ diff --git a/coregrind/m_syswrap/syswrap-mips32-linux.c b/coregrind/m_syswrap/syswrap-mips32-linux.c index d1f5dfce3..c4d7a6620 100644 --- a/coregrind/m_syswrap/syswrap-mips32-linux.c +++ b/coregrind/m_syswrap/syswrap-mips32-linux.c @@ -1176,6 +1176,7 @@ static SyscallTableEntry syscall_main_table[] = { LINX_ (__NR_faccessat2, sys_faccessat2), // 439 LINXY(__NR_epoll_pwait2, sys_epoll_pwait2), // 441 + LINX_(__NR_mount_setattr, sys_mount_setattr), // 442 LINX_(__NR_quotactl_fd, sys_quotactl_fd), // 443 LINXY(__NR_landlock_create_ruleset, sys_landlock_create_ruleset), // 444 diff --git a/coregrind/m_syswrap/syswrap-mips64-linux.c b/coregrind/m_syswrap/syswrap-mips64-linux.c index 64fb647b1..45af0a3fd 100644 --- a/coregrind/m_syswrap/syswrap-mips64-linux.c +++ b/coregrind/m_syswrap/syswrap-mips64-linux.c @@ -646,6 +646,7 @@ static SyscallTableEntry syscall_main_table[] = { GENX_ (__NR_acct, sys_acct), GENX_ (__NR_settimeofday, sys_settimeofday), LINX_ (__NR_mount, sys_mount), + LINX_ (__NR_mount_setattr, sys_mount_setattr), LINX_ (__NR_umount2, sys_umount), PLAX_ (__NR_swapon, sys_swapon), PLAX_ (__NR_swapoff, sys_swapoff), diff --git a/coregrind/m_syswrap/syswrap-ppc32-linux.c b/coregrind/m_syswrap/syswrap-ppc32-linux.c index 94010bcee..8bb0a04f5 100644 --- a/coregrind/m_syswrap/syswrap-ppc32-linux.c +++ b/coregrind/m_syswrap/syswrap-ppc32-linux.c @@ -1075,6 +1075,7 @@ static SyscallTableEntry syscall_table[] = { LINX_(__NR_faccessat2, sys_faccessat2), // 439 LINXY (__NR_epoll_pwait2, sys_epoll_pwait2), // 441 + LINX_ (__NR_mount_setattr, sys_mount_setattr), // 442 LINX_ (__NR_quotactl_fd, sys_quotactl_fd), // 443 LINXY(__NR_landlock_create_ruleset, sys_landlock_create_ruleset), // 444 diff --git a/coregrind/m_syswrap/syswrap-ppc64-linux.c b/coregrind/m_syswrap/syswrap-ppc64-linux.c index da81c0757..0f5111728 100644 --- a/coregrind/m_syswrap/syswrap-ppc64-linux.c +++ b/coregrind/m_syswrap/syswrap-ppc64-linux.c @@ -1053,6 +1053,7 @@ static SyscallTableEntry syscall_table[] = { LINX_(__NR_faccessat2, sys_faccessat2), // 439 LINXY (__NR_epoll_pwait2, sys_epoll_pwait2), // 441 + LINX_ (__NR_mount_setattr, sys_mount_setattr), // 442 LINX_ (__NR_quotactl_fd, sys_quotactl_fd), // 443 LINXY(__NR_landlock_create_ruleset, sys_landlock_create_ruleset), // 444 diff --git a/coregrind/m_syswrap/syswrap-riscv64-linux.c b/coregrind/m_syswrap/syswrap-riscv64-linux.c index dc175e3ec..d806b92b8 100644 --- a/coregrind/m_syswrap/syswrap-riscv64-linux.c +++ b/coregrind/m_syswrap/syswrap-riscv64-linux.c @@ -595,6 +595,7 @@ static SyscallTableEntry syscall_main_table[] = { LINXY(__NR_pidfd_getfd, sys_pidfd_getfd), /* 438 */ LINX_(__NR_faccessat2, sys_faccessat2), /* 439 */ LINXY(__NR_epoll_pwait2, sys_epoll_pwait2), /* 441 */ + LINX_(__NR_mount_setattr, sys_mount_setattr), /* 442 */ LINX_(__NR_quotactl_fd, sys_quotactl_fd), /* 443 */ LINXY(__NR_landlock_create_ruleset, sys_landlock_create_ruleset), /* 444 */ LINX_(__NR_landlock_add_rule, sys_landlock_add_rule), /* 445 */ diff --git a/coregrind/m_syswrap/syswrap-s390x-linux.c b/coregrind/m_syswrap/syswrap-s390x-linux.c index fba3d96fb..643549c64 100644 --- a/coregrind/m_syswrap/syswrap-s390x-linux.c +++ b/coregrind/m_syswrap/syswrap-s390x-linux.c @@ -886,6 +886,7 @@ static SyscallTableEntry syscall_table[] = { LINX_(__NR_faccessat2, sys_faccessat2), // 439 LINXY(__NR_epoll_pwait2, sys_epoll_pwait2), // 441 + LINX_(__NR_mount_setattr, sys_mount_setattr), // 442 LINX_(__NR_quotactl_fd, sys_quotactl_fd), // 443 LINXY(__NR_landlock_create_ruleset, sys_landlock_create_ruleset), // 444 diff --git a/coregrind/m_syswrap/syswrap-x86-linux.c b/coregrind/m_syswrap/syswrap-x86-linux.c index 7d2d495a9..42a69cb96 100644 --- a/coregrind/m_syswrap/syswrap-x86-linux.c +++ b/coregrind/m_syswrap/syswrap-x86-linux.c @@ -1668,6 +1668,7 @@ static SyscallTableEntry syscall_table[] = { LINX_(__NR_faccessat2, sys_faccessat2), // 439 LINXY(__NR_epoll_pwait2, sys_epoll_pwait2), // 441 + LINX_(__NR_mount_setattr, sys_mount_setattr), // 442 LINX_(__NR_quotactl_fd, sys_quotactl_fd), // 443 LINXY(__NR_landlock_create_ruleset, sys_landlock_create_ruleset), // 444 diff --git a/include/vki/vki-scnums-shared-linux.h b/include/vki/vki-scnums-shared-linux.h index c5f33e935..518131a1f 100644 --- a/include/vki/vki-scnums-shared-linux.h +++ b/include/vki/vki-scnums-shared-linux.h @@ -48,6 +48,7 @@ #define __NR_epoll_pwait2 441 +#define __NR_mount_setattr 442 #define __NR_quotactl_fd 443 #define __NR_landlock_create_ruleset 444 #define __NR_landlock_add_rule 445 -- 2.47.3