All of lore.kernel.org
 help / color / mirror / Atom feed
* [PULL 0/2] Linux user for v11.1 patches
@ 2026-07-13 14:35 Helge Deller
  2026-07-13 14:35 ` [PULL 1/2] linux-user: Validate guest-passed dm_ioctl data_size Helge Deller
  2026-07-13 14:35 ` [PULL 2/2] linux-user/alpha: populate AT_HWCAP from env->amask Helge Deller
  0 siblings, 2 replies; 3+ messages in thread
From: Helge Deller @ 2026-07-13 14:35 UTC (permalink / raw)
  To: Stefan Hajnoczi, qemu-devel
  Cc: Laurent Vivier, Pierrick Bouvier, Helge Deller

From: Helge Deller <deller@gmx.de>

The following changes since commit 916ab315cc2b3a3825ebb399d83339660144d5bd:

  Merge tag 'pull-nvme-20260707' of https://gitlab.com/birkelund/qemu into staging (2026-07-07 07:09:38 +0200)

are available in the Git repository at:

  https://github.com/hdeller/qemu-hppa.git tags/linux-user-for-v11.1-pull-request

for you to fetch changes up to 7a2e863f9dd52883d6f59bb425f30609fc14aee4:

  linux-user/alpha: populate AT_HWCAP from env->amask (2026-07-13 16:16:31 +0200)

----------------------------------------------------------------
linux-user-for-v11.1 pull request

Please pull two fixes for linux-user for v11.1:
- Validate guest-passed dm_ioctl data_size
- Alpha: Fix programs using getauxval(AT_HWCAP) to detect BWX/FIX/CIX

----------------------------------------------------------------

Matt Turner (1):
  linux-user/alpha: populate AT_HWCAP from env->amask

Peter Maydell (1):
  linux-user: Validate guest-passed dm_ioctl data_size

 linux-user/alpha/elfload.c    | 11 +++++++++++
 linux-user/alpha/target_elf.h |  1 +
 linux-user/syscall.c          | 30 ++++++++++++++++++++++++++----
 3 files changed, 38 insertions(+), 4 deletions(-)

-- 
2.54.0



^ permalink raw reply	[flat|nested] 3+ messages in thread

* [PULL 1/2] linux-user: Validate guest-passed dm_ioctl data_size
  2026-07-13 14:35 [PULL 0/2] Linux user for v11.1 patches Helge Deller
@ 2026-07-13 14:35 ` Helge Deller
  2026-07-13 14:35 ` [PULL 2/2] linux-user/alpha: populate AT_HWCAP from env->amask Helge Deller
  1 sibling, 0 replies; 3+ messages in thread
From: Helge Deller @ 2026-07-13 14:35 UTC (permalink / raw)
  To: Stefan Hajnoczi, qemu-devel
  Cc: Laurent Vivier, Pierrick Bouvier, Helge Deller, Peter Maydell

From: Peter Maydell <peter.maydell@linaro.org>

In do_ioctl_dm() we work with a struct dm_ioctl from the guest.  This
has a fixed initial part, and then a variable data part; the guest
tells us how long that part is by setting the data_size field.  The
data_size is supposed to include the length of the fixed parts of the
struct dm_ioctl.  Currently we don't validate anything about the
guest-provided data_size, and we use it to allocate a buffer which we
then copy the fixed part of the dm_ioctl struct into.  This means
that if the guest passes a very small data_size the copy of the fixed
part will overrun the buffer.

Perform the same sanitizing of the minimum and maximum limits of the
data_size that the kernel does in drivers/md/dm-ioctl.c in the
copy_params() function.

Cc: qemu-stable@nongnu.org
Fixes: 56e904ecb2018 ("linux-user: implement device mapper ioctls")
Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/3736
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Helge Deller <deller@gmx.de>
Signed-off-by: Helge Deller <deller@gmx.de>
---
 linux-user/syscall.c | 30 ++++++++++++++++++++++++++----
 1 file changed, 26 insertions(+), 4 deletions(-)

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index d257fb9ca9..3f060ee8b6 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -5088,6 +5088,9 @@ do_ioctl_usbdevfs_submiturb(const IOCTLEntry *ie, uint8_t *buf_temp,
 }
 #endif /* CONFIG_USBFS */
 
+#define DM_MAX_TARGETS                  1048576
+#define DM_MAX_TARGET_PARAMS            1024
+
 static abi_long do_ioctl_dm(const IOCTLEntry *ie, uint8_t *buf_temp, int fd,
                             int cmd, abi_long arg)
 {
@@ -5100,6 +5103,7 @@ static abi_long do_ioctl_dm(const IOCTLEntry *ie, uint8_t *buf_temp, int fd,
     abi_long ret;
     void *big_buf = NULL;
     char *host_data;
+    const size_t minimum_data_size = offsetof(struct dm_ioctl, data);
 
     arg_type++;
     target_size = thunk_type_size(arg_type, 0);
@@ -5111,9 +5115,26 @@ static abi_long do_ioctl_dm(const IOCTLEntry *ie, uint8_t *buf_temp, int fd,
     thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
     unlock_user(argptr, arg, 0);
 
-    /* buf_temp is too small, so fetch things into a bigger buffer */
-    big_buf = g_malloc0(((struct dm_ioctl*)buf_temp)->data_size * 2);
-    memcpy(big_buf, buf_temp, target_size);
+    /* At this point this includes the size of the fixed dm_ioctl parts */
+    guest_data_size = ((struct dm_ioctl *)buf_temp)->data_size;
+
+    if (guest_data_size < minimum_data_size ||
+        guest_data_size > DM_MAX_TARGETS * DM_MAX_TARGET_PARAMS) {
+        ret = -TARGET_EINVAL;
+        goto out;
+    }
+
+    /*
+     * buf_temp is too small, so fetch things into a bigger buffer. Here
+     * we copy all of the fixed parts of struct dm_ioctl but not the
+     * data at the end (which in the struct is "char data[7]" but in
+     * reality is command-specific and might be nothing or might be
+     * much larger, as defined by data_size). We know struct dm_ioctl's
+     * size is not target specific so we don't need to distinguish between
+     * its minimum size for the host vs the target.
+     */
+    big_buf = g_malloc0(guest_data_size * 2);
+    memcpy(big_buf, buf_temp, minimum_data_size);
     buf_temp = big_buf;
     host_dm = big_buf;
 
@@ -5122,7 +5143,8 @@ static abi_long do_ioctl_dm(const IOCTLEntry *ie, uint8_t *buf_temp, int fd,
         ret = -TARGET_EINVAL;
         goto out;
     }
-    guest_data_size = host_dm->data_size - host_dm->data_start;
+    /* Adjust down to only the size of the payload */
+    guest_data_size -= host_dm->data_start;
     host_data = (char*)host_dm + host_dm->data_start;
 
     argptr = lock_user(VERIFY_READ, guest_data, guest_data_size, 1);
-- 
2.54.0



^ permalink raw reply related	[flat|nested] 3+ messages in thread

* [PULL 2/2] linux-user/alpha: populate AT_HWCAP from env->amask
  2026-07-13 14:35 [PULL 0/2] Linux user for v11.1 patches Helge Deller
  2026-07-13 14:35 ` [PULL 1/2] linux-user: Validate guest-passed dm_ioctl data_size Helge Deller
@ 2026-07-13 14:35 ` Helge Deller
  1 sibling, 0 replies; 3+ messages in thread
From: Helge Deller @ 2026-07-13 14:35 UTC (permalink / raw)
  To: Stefan Hajnoczi, qemu-devel
  Cc: Laurent Vivier, Pierrick Bouvier, Helge Deller, Matt Turner

From: Matt Turner <mattst88@gmail.com>

Alpha has never set AT_HWCAP in linux-user emulation, so getauxval(AT_HWCAP)
always returned 0 regardless of the emulated CPU model.

The Linux kernel computes ELF_HWCAP as ~amask(-1), i.e. the set of ISA
extension bits that the amask instruction reports as supported (cleared in
its output).  env->amask stores exactly those bits with the same layout
(BWX=0x1, FIX=0x2, CIX=0x4, MVI=0x100, TRAP=0x200, PREFETCH=0x1000), so
returning it directly from get_elf_hwcap matches the kernel convention.

Add HAVE_ELF_HWCAP to target_elf.h and implement get_elf_hwcap() in
elfload.c to expose the emulated CPU's capability mask to user-space
programs via the auxiliary vector.

Without this fix, programs using getauxval(AT_HWCAP) to detect BWX/FIX/CIX
(such as glibc's memcpy or JIT compilers targeting Alpha) incorrectly
concluded that no extensions were available even when emulating ev56+.

Signed-off-by: Matt Turner <mattst88@gmail.com>
Cc: qemu-stable@nongnu.org
Reviewed-by: Helge Deller <deller@gmx.de>
Signed-off-by: Helge Deller <deller@gmx.de>
---
 linux-user/alpha/elfload.c    | 11 +++++++++++
 linux-user/alpha/target_elf.h |  1 +
 2 files changed, 12 insertions(+)

diff --git a/linux-user/alpha/elfload.c b/linux-user/alpha/elfload.c
index 1969f620a5..7be9e466b6 100644
--- a/linux-user/alpha/elfload.c
+++ b/linux-user/alpha/elfload.c
@@ -6,6 +6,17 @@
 #include "target_elf.h"
 
 
+abi_ulong get_elf_hwcap(CPUState *cs)
+{
+    /*
+     * The Linux kernel computes ELF_HWCAP as ~amask(-1), which clears a bit
+     * for each supported ISA extension.  env->amask stores exactly those bits
+     * set for the extensions supported by the emulated CPU model, matching
+     * the kernel's convention: bit set in AT_HWCAP ↔ extension present.
+     */
+    return cpu_env(cs)->amask;
+}
+
 void elf_core_copy_regs(target_elf_gregset_t *r, const CPUAlphaState *env)
 {
     int i;
diff --git a/linux-user/alpha/target_elf.h b/linux-user/alpha/target_elf.h
index 4987ae3944..dd90c6f783 100644
--- a/linux-user/alpha/target_elf.h
+++ b/linux-user/alpha/target_elf.h
@@ -12,6 +12,7 @@
 #define ELF_MACHINE             EM_ALPHA
 
 #define HAVE_ELF_CORE_DUMP      1
+#define HAVE_ELF_HWCAP          1
 
 /*
  * Matches the kernel's elf_gregset_t (ELF_NGREG = 33):
-- 
2.54.0



^ permalink raw reply related	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2026-07-13 14:36 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-13 14:35 [PULL 0/2] Linux user for v11.1 patches Helge Deller
2026-07-13 14:35 ` [PULL 1/2] linux-user: Validate guest-passed dm_ioctl data_size Helge Deller
2026-07-13 14:35 ` [PULL 2/2] linux-user/alpha: populate AT_HWCAP from env->amask Helge Deller

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.