Hi,
在 2026/5/29 03:07, Pierrick Bouvier 写道:
On 5/27/2026 3:11 AM, Xinhui Yang wrote:
This series of syscalls replaces the old mount(2) syscall with a series
of syscalls that operates around a filesystem context. This series of
syscalls is available since Linux 5.2 and glibc 2.36+.
Their users include systemd since v259 and libmount from util-linux, and
possibly other widely used projects.
Preliminary checks are implemented to ensure the validity of the
interface.
Signed-off-by: Xinhui Yang <[email protected]>
---
linux-user/syscall.c | 81 ++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 81 insertions(+)
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 7d7a7b489c..2ff80f4dfa 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -14412,6 +14412,87 @@ 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_fsopen)
+ case TARGET_NR_fsopen:
+ {
+ p = lock_user_string(arg1);
+ if (!p) {
+ return -TARGET_EFAULT;
+ }
+ ret = get_errno(fsopen(p, arg2));
+ unlock_user(p, arg1, 0);
+ }
+ return ret;
+ case TARGET_NR_fsconfig:
+ {
+ /*
+ * fsconfig(int, int, char *, void *, int)
+ * NOTE: p4 is nullable and its type might not be a string.
+ */
+ void *p3, *p4;
+ int cmd = (int) arg2;
+ switch (cmd) {
+ case FSCONFIG_SET_BINARY:
+ case FSCONFIG_SET_STRING:
+ case FSCONFIG_SET_PATH:
+ case FSCONFIG_SET_PATH_EMPTY:
+ p3 = lock_user_string(arg3);
+ if (cmd != FSCONFIG_SET_BINARY) {
+ /* key and value must be strings. */
+ p4 = lock_user_string(arg4);
+ } else {
+ /* Otherise the value must be a raw buffer. */
+ p4 = lock_user(VERIFY_READ, arg4, arg5, 1);
+ }
+ if (!p3 || !p4) {
+ return -TARGET_EFAULT;
+ }
Might leave with locked p3 is p4 fails.
You can add another early return just after p3 and unlock p3 in this if.
Thanks! Sending v3.
+ ret = get_errno(fsconfig(arg1, arg2, p3, p4, arg5));
+ unlock_user(p3, arg3, 0);
+ unlock_user(p4, arg4, 0);
+ break;
+
+ case FSCONFIG_SET_FLAG:
+ case FSCONFIG_SET_FD:
+ /* value must be NULL. */
+ p3 = lock_user_string(arg3);
+ if (!p3 || arg4) {
+ return -TARGET_EFAULT;
+ }
+ ret = get_errno(fsconfig(arg1, arg2, p3, NULL, arg5));
Similar to above (if arg4) { unlock... }
+ unlock_user(p3, arg3, 0);
+ break;
+ case FSCONFIG_CMD_CREATE:
+ case FSCONFIG_CMD_RECONFIGURE:
+#ifdef FSCONFIG_CMD_CREATE_EXCL
+ /*
+ * FSCONFIG_CMD_CREATE_EXCL is only available since Linux
+ * 6.6. Guarding it to allow building with pre-6.6 headers.
+ */
+ case FSCONFIG_CMD_CREATE_EXCL:
+#endif
+ /* key and value must be NULL, aux must be 0. */
+ if (arg3 || arg4 || arg5) {
+ return -TARGET_EFAULT;
+ }
+ ret = get_errno(fsconfig(arg1, arg2, NULL, NULL, 0));
+ break;
+ default:
+ return -TARGET_EFAULT;
+ }
+ }
+ return ret;
+ case TARGET_NR_fsmount:
+ ret = get_errno(fsmount(arg1, arg2, arg3));
+ return ret;
+ case TARGET_NR_fspick:
+ {
+ p = lock_user_string(arg2);
+ ret = get_errno(fspick(arg1, p, arg3));
+ unlock_user(p, arg2, 0);
+ }
+ return ret;
+#endif
default:
qemu_log_mask(LOG_UNIMP, "Unsupported syscall: %d\n", num);
return -TARGET_ENOSYS;
Xinhui