From: Helge Deller <deller@kernel.org>
To: Stefan Hajnoczi <stefanha@gmail.com>, qemu-devel@nongnu.org
Cc: "Pierrick Bouvier" <pierrick.bouvier@oss.qualcomm.com>,
"Philippe Mathieu-Daudé" <philmd@mailo.com>,
"Matt Turner" <mattst88@gmail.com>,
"Laurent Vivier" <laurent@vivier.eu>,
"Helge Deller" <deller@gmx.de>
Subject: [PULL 1/7] linux-user: implement mount_setattr(2)
Date: Wed, 12 Aug 2026 22:37:19 +0200 [thread overview]
Message-ID: <20260812203725.10694-2-deller@kernel.org> (raw)
In-Reply-To: <20260812203725.10694-1-deller@kernel.org>
From: Matt Turner <mattst88@gmail.com>
mount_setattr() was in the syscall tables but had no implementation, so
guests always got -ENOSYS. systemd uses it when setting up per-unit
credential mounts, which fails the affected units with EXIT_CREDENTIALS.
struct mount_attr is an extensible struct like open_how, so handle it the
same way openat2() does: reject sizes smaller than the ver0 struct and
require any unknown trailing bytes to be zero. All of its fields are
64-bit, and the MOUNT_ATTR_* and MS_* propagation values are identical on
every target, so only the byte order needs fixing up.
Signed-off-by: Matt Turner <mattst88@gmail.com>
Reviewed-by: Helge Deller <deller@gmx.de>
Signed-off-by: Helge Deller <deller@gmx.de>
---
linux-user/strace.list | 3 +++
linux-user/syscall.c | 44 +++++++++++++++++++++++++++++++++++++++
linux-user/syscall_defs.h | 13 ++++++++++++
3 files changed, 60 insertions(+)
diff --git a/linux-user/strace.list b/linux-user/strace.list
index 25ace05187..e952f15d20 100644
--- a/linux-user/strace.list
+++ b/linux-user/strace.list
@@ -1737,3 +1737,6 @@
#ifdef TARGET_NR_fspick
{ TARGET_NR_fspick, "fspick", "%s(%d,%s,%d)", NULL, NULL },
#endif
+#ifdef TARGET_NR_mount_setattr
+{ TARGET_NR_mount_setattr, "mount_setattr", "%s(%d,%s,%d,%p,%d)", NULL, NULL },
+#endif
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index dc028686f4..cfa68dfbdb 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -9735,6 +9735,13 @@ _syscall5(int, sys_move_mount, int, __from_dfd, const char *, __from_pathname,
int, __to_dfd, const char *, __to_pathname, unsigned int, flag)
#endif
+#if defined(TARGET_NR_mount_setattr) && defined(__NR_mount_setattr)
+#define __NR_sys_mount_setattr __NR_mount_setattr
+_syscall5(int, sys_mount_setattr, int, dfd, const char *, path,
+ unsigned int, flags, struct mount_attr_ver0 *, uattr,
+ size_t, usize)
+#endif
+
#if defined(TARGET_NR_fsopen) && defined(__NR_fsopen)
#define __NR_sys_fsopen __NR_fsopen
_syscall2(int, sys_fsopen, const char *, fs_name, unsigned int, flags);
@@ -14480,6 +14487,43 @@ static abi_long do_syscall1(CPUArchState *cpu_env, int num, abi_long arg1,
return do_map_shadow_stack(cpu_env, arg1, arg2, arg3);
#endif
+#if defined(TARGET_NR_mount_setattr) && defined(__NR_mount_setattr)
+ case TARGET_NR_mount_setattr:
+ {
+ struct mount_attr_ver0 attr = {};
+ abi_ulong usize = arg5;
+
+ if (usize < sizeof(struct target_mount_attr_ver0)) {
+ return -TARGET_EINVAL;
+ }
+ ret = copy_struct_from_user(&attr, sizeof(attr), arg4, usize);
+ if (ret) {
+ if (ret == -TARGET_E2BIG) {
+ qemu_log_mask(LOG_UNIMP,
+ "Unimplemented mount_setattr mount_attr "
+ "size: " TARGET_ABI_FMT_lu "\n", usize);
+ }
+ return ret;
+ }
+ /*
+ * MOUNT_ATTR_* and the MS_* propagation flags have the same
+ * values on all targets, so only byte order needs fixing up.
+ */
+ attr.attr_set = tswap64(attr.attr_set);
+ attr.attr_clr = tswap64(attr.attr_clr);
+ attr.propagation = tswap64(attr.propagation);
+ attr.userns_fd = tswap64(attr.userns_fd);
+
+ p = lock_user_string(arg2);
+ if (!p) {
+ return -TARGET_EFAULT;
+ }
+ ret = get_errno(sys_mount_setattr(arg1, p, arg3, &attr,
+ sizeof(attr)));
+ unlock_user(p, arg2, 0);
+ }
+ return ret;
+#endif
#if defined(TARGET_NR_fsopen) && defined(__NR_fsopen)
case TARGET_NR_fsopen:
{
diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h
index e033c7db34..e28853c93b 100644
--- a/linux-user/syscall_defs.h
+++ b/linux-user/syscall_defs.h
@@ -2770,6 +2770,19 @@ struct target_open_how_ver0 {
abi_ullong mode;
abi_ullong resolve;
};
+/* from kernel's include/uapi/linux/mount.h */
+struct mount_attr_ver0 {
+ uint64_t attr_set;
+ uint64_t attr_clr;
+ uint64_t propagation;
+ uint64_t userns_fd;
+};
+struct target_mount_attr_ver0 {
+ abi_ullong attr_set;
+ abi_ullong attr_clr;
+ abi_ullong propagation;
+ abi_ullong userns_fd;
+};
#ifndef RESOLVE_NO_MAGICLINKS
#define RESOLVE_NO_MAGICLINKS 0x02
#endif
--
2.54.0
next prev parent reply other threads:[~2026-08-12 20:38 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-12 20:37 [PULL 0/7] Linux user patches Helge Deller
2026-08-12 20:37 ` Helge Deller [this message]
2026-08-12 20:37 ` [PULL 2/7] linux-user: support writing floating-point registers to a core dump Helge Deller
2026-08-12 20:37 ` [PULL 3/7] linux-user/alpha: write the " Helge Deller
2026-08-12 20:37 ` [PULL 4/7] linux-user/mips: " Helge Deller
2026-08-12 20:37 ` [PULL 5/7] linux-user/hppa: " Helge Deller
2026-08-12 20:37 ` [PULL 6/7] linux-user/riscv: " Helge Deller
2026-08-12 20:37 ` [PULL 7/7] linux-user/sh4: " Helge Deller
2026-08-13 0:23 ` [PULL 0/7] Linux user patches Richard Henderson
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260812203725.10694-2-deller@kernel.org \
--to=deller@kernel.org \
--cc=deller@gmx.de \
--cc=laurent@vivier.eu \
--cc=mattst88@gmail.com \
--cc=philmd@mailo.com \
--cc=pierrick.bouvier@oss.qualcomm.com \
--cc=qemu-devel@nongnu.org \
--cc=stefanha@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.