mirror of
https://github.com/qemu/qemu.git
synced 2026-04-05 22:00:58 +00:00
linux-user: fix name_to_handle_at when AT_HANDLE_MNT_ID_UNIQUE flag is set
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> Message-id: 20260325-fix-name-to-handle-at-v1-1-49fb922e6fd3@craftyguy.net Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
committed by
Peter Maydell
parent
8330da591e
commit
22966937f4
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user