[PATCH] linux-user: fix name_to_handle_at when AT_HANDLE_MNT_ID_UNIQUE flag is set

Clayton Craft posted 1 patch 1 week ago
Patches applied successfully (tree, apply log)
git fetch https://github.com/patchew-project/qemu tags/patchew/20260325-fix-name-to-handle-at-v1-1-49fb922e6fd3@craftyguy.net
Maintainers: Laurent Vivier <laurent@vivier.eu>, Pierrick Bouvier <pierrick.bouvier@linaro.org>
linux-user/syscall.c | 21 ++++++++++++++++++---
1 file changed, 18 insertions(+), 3 deletions(-)
[PATCH] linux-user: fix name_to_handle_at when AT_HANDLE_MNT_ID_UNIQUE flag is set
Posted by Clayton Craft 1 week ago
Linux 6.12 added AT_HANDLE_MNT_ID_UNIQUE, which indicates that mount_id
is 64-bits. If name_to_handle_at is called with this flag set then qemu
passes a 4 byte int to the kernel, which then tries to store 8 bytes in
a 4 byte variable, causing a SIGSEGV[1][2].

This stores mount_id in a 64-bit var if the flag is set.

1. https://gitlab.postmarketos.org/postmarketOS/pmaports/-/work_items/4431
2. https://github.com/systemd/systemd/issues/41279

Signed-off-by: Clayton Craft <craftyguy@postmarketos.org>
---
This fixes a crash experienced recently while running qemu user mode
with e.g. systemd which set AT_HANDLE_MNT_ID_UNIQUE when calling
name_to_handle_at. AT_HANDLE_MNT_ID_UNIQUE was added in Linux 6.12.

I'm a bit unsure of defining AT_HANDLE_MNT_ID_UNIQUE like this,
it's part of linux/fcntl.h but this header isn't included in
qemu/linux-headers.

1. https://gitlab.postmarketos.org/postmarketOS/pmaports/-/work_items/4431
2. https://github.com/systemd/systemd/issues/41279
---
 linux-user/syscall.c | 21 ++++++++++++++++++---
 1 file changed, 18 insertions(+), 3 deletions(-)

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 7832a1aba5..3cb00c643e 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -8166,6 +8166,9 @@ static int do_futex(CPUState *cpu, bool time64, target_ulong uaddr,
 #endif
 
 #if defined(TARGET_NR_name_to_handle_at) && defined(CONFIG_OPEN_BY_HANDLE)
+#ifndef AT_HANDLE_MNT_ID_UNIQUE
+#define AT_HANDLE_MNT_ID_UNIQUE 0x001
+#endif
 static abi_long do_name_to_handle_at(abi_long dirfd, abi_long pathname,
                                      abi_long handle, abi_long mount_id,
                                      abi_long flags)
@@ -8173,6 +8176,7 @@ static abi_long do_name_to_handle_at(abi_long dirfd, abi_long pathname,
     struct file_handle *target_fh;
     struct file_handle *fh;
     int mid = 0;
+    uint64_t mid64 = 0;
     abi_long ret;
     char *name;
     unsigned int size, total_size;
@@ -8196,7 +8200,12 @@ static abi_long do_name_to_handle_at(abi_long dirfd, abi_long pathname,
     fh = g_malloc0(total_size);
     fh->handle_bytes = size;
 
-    ret = get_errno(name_to_handle_at(dirfd, path(name), fh, &mid, flags));
+    if (flags & AT_HANDLE_MNT_ID_UNIQUE) {
+        ret = get_errno(name_to_handle_at(dirfd, path(name), fh,
+                                          (int *)&mid64, flags));
+    } else {
+        ret = get_errno(name_to_handle_at(dirfd, path(name), fh, &mid, flags));
+    }
     unlock_user(name, pathname, 0);
 
     /* man name_to_handle_at(2):
@@ -8210,8 +8219,14 @@ static abi_long do_name_to_handle_at(abi_long dirfd, abi_long pathname,
     g_free(fh);
     unlock_user(target_fh, handle, total_size);
 
-    if (put_user_s32(mid, mount_id)) {
-        return -TARGET_EFAULT;
+    if (flags & AT_HANDLE_MNT_ID_UNIQUE) {
+        if (put_user_u64(mid64, mount_id)) {
+            return -TARGET_EFAULT;
+        }
+    } else {
+        if (put_user_s32(mid, mount_id)) {
+            return -TARGET_EFAULT;
+        }
     }
 
     return ret;

---
base-commit: 007b29752ed06e467d3c830bc2c17a8851f8bcd3
change-id: 20260325-fix-name-to-handle-at-02208f294e88

Best regards,
-- 
Clayton Craft <clayton@craftyguy.net>
Re: [PATCH] linux-user: fix name_to_handle_at when AT_HANDLE_MNT_ID_UNIQUE flag is set
Posted by Helge Deller 1 week ago
On 3/26/26 06:59, Clayton Craft wrote:
> Linux 6.12 added AT_HANDLE_MNT_ID_UNIQUE, which indicates that mount_id
> is 64-bits. If name_to_handle_at is called with this flag set then qemu
> passes a 4 byte int to the kernel, which then tries to store 8 bytes in
> a 4 byte variable, causing a SIGSEGV[1][2].
> 
> This stores mount_id in a 64-bit var if the flag is set.
> 
> 1. https://gitlab.postmarketos.org/postmarketOS/pmaports/-/work_items/4431
> 2. https://github.com/systemd/systemd/issues/41279
> 
> Signed-off-by: Clayton Craft <craftyguy@postmarketos.org>

Reviewed-by: Helge Deller <deller@gmx.de>

Helge

> ---
> This fixes a crash experienced recently while running qemu user mode
> with e.g. systemd which set AT_HANDLE_MNT_ID_UNIQUE when calling
> name_to_handle_at. AT_HANDLE_MNT_ID_UNIQUE was added in Linux 6.12.
> 
> I'm a bit unsure of defining AT_HANDLE_MNT_ID_UNIQUE like this,
> it's part of linux/fcntl.h but this header isn't included in
> qemu/linux-headers.
> 
> 1. https://gitlab.postmarketos.org/postmarketOS/pmaports/-/work_items/4431
> 2. https://github.com/systemd/systemd/issues/41279
> ---
>   linux-user/syscall.c | 21 ++++++++++++++++++---
>   1 file changed, 18 insertions(+), 3 deletions(-)
> 
> diff --git a/linux-user/syscall.c b/linux-user/syscall.c
> index 7832a1aba5..3cb00c643e 100644
> --- a/linux-user/syscall.c
> +++ b/linux-user/syscall.c
> @@ -8166,6 +8166,9 @@ static int do_futex(CPUState *cpu, bool time64, target_ulong uaddr,
>   #endif
>   
>   #if defined(TARGET_NR_name_to_handle_at) && defined(CONFIG_OPEN_BY_HANDLE)
> +#ifndef AT_HANDLE_MNT_ID_UNIQUE
> +#define AT_HANDLE_MNT_ID_UNIQUE 0x001
> +#endif
>   static abi_long do_name_to_handle_at(abi_long dirfd, abi_long pathname,
>                                        abi_long handle, abi_long mount_id,
>                                        abi_long flags)
> @@ -8173,6 +8176,7 @@ static abi_long do_name_to_handle_at(abi_long dirfd, abi_long pathname,
>       struct file_handle *target_fh;
>       struct file_handle *fh;
>       int mid = 0;
> +    uint64_t mid64 = 0;
>       abi_long ret;
>       char *name;
>       unsigned int size, total_size;
> @@ -8196,7 +8200,12 @@ static abi_long do_name_to_handle_at(abi_long dirfd, abi_long pathname,
>       fh = g_malloc0(total_size);
>       fh->handle_bytes = size;
>   
> -    ret = get_errno(name_to_handle_at(dirfd, path(name), fh, &mid, flags));
> +    if (flags & AT_HANDLE_MNT_ID_UNIQUE) {
> +        ret = get_errno(name_to_handle_at(dirfd, path(name), fh,
> +                                          (int *)&mid64, flags));
> +    } else {
> +        ret = get_errno(name_to_handle_at(dirfd, path(name), fh, &mid, flags));
> +    }
>       unlock_user(name, pathname, 0);
>   
>       /* man name_to_handle_at(2):
> @@ -8210,8 +8219,14 @@ static abi_long do_name_to_handle_at(abi_long dirfd, abi_long pathname,
>       g_free(fh);
>       unlock_user(target_fh, handle, total_size);
>   
> -    if (put_user_s32(mid, mount_id)) {
> -        return -TARGET_EFAULT;
> +    if (flags & AT_HANDLE_MNT_ID_UNIQUE) {
> +        if (put_user_u64(mid64, mount_id)) {
> +            return -TARGET_EFAULT;
> +        }
> +    } else {
> +        if (put_user_s32(mid, mount_id)) {
> +            return -TARGET_EFAULT;
> +        }
>       }
>   
>       return ret;
> 
> ---
> base-commit: 007b29752ed06e467d3c830bc2c17a8851f8bcd3
> change-id: 20260325-fix-name-to-handle-at-02208f294e88
> 
> Best regards,
Re: [PATCH] linux-user: fix name_to_handle_at when AT_HANDLE_MNT_ID_UNIQUE flag is set
Posted by Peter Maydell 2 days, 3 hours ago
On Thu, 26 Mar 2026 at 14:49, Helge Deller <deller@gmx.de> wrote:
>
> On 3/26/26 06:59, Clayton Craft wrote:
> > Linux 6.12 added AT_HANDLE_MNT_ID_UNIQUE, which indicates that mount_id
> > is 64-bits. If name_to_handle_at is called with this flag set then qemu
> > passes a 4 byte int to the kernel, which then tries to store 8 bytes in
> > a 4 byte variable, causing a SIGSEGV[1][2].
> >
> > This stores mount_id in a 64-bit var if the flag is set.
> >
> > 1. https://gitlab.postmarketos.org/postmarketOS/pmaports/-/work_items/4431
> > 2. https://github.com/systemd/systemd/issues/41279
> >
> > Signed-off-by: Clayton Craft <craftyguy@postmarketos.org>
>
> Reviewed-by: Helge Deller <deller@gmx.de>

I'm putting together a pullreq with a few recent linux-user patches so
we can get them fixed in rc2; I've included this one.

thanks
-- PMM