summary refs log tree commit diff stats
path: root/linux-user/syscall.c
diff options
context:
space:
mode:
authorStefan <stefan-guix@vodafonemail.de>2021-01-09 19:59:42 +0100
committerLaurent Vivier <laurent@vivier.eu>2021-02-13 22:50:50 +0100
commit4df7b7fac84ba570bb33970659296555896232b6 (patch)
tree5ded9d77a9416543c7e6131c81a757739b4736b3 /linux-user/syscall.c
parentccc5ccc17f8cfbfd87d9aede5d12a2d47c56e712 (diff)
downloadfocaccia-qemu-4df7b7fac84ba570bb33970659296555896232b6.tar.gz
focaccia-qemu-4df7b7fac84ba570bb33970659296555896232b6.zip
linux-user/syscall: Fix do_ioctl_ifconf() for 64 bit targets.
The sizeof(struct ifreq) is 40 for 64 bit and 32 for 32 bit architectures.
This structure contains a union of other structures, of which struct ifmap
is the biggest for 64 bit architectures. Calling ioclt(…, SIOCGIFCONF, …)
fills a struct sockaddr of that union, and do_ioctl_ifconf() only considered
that struct sockaddr for the size of the union, which has the same size as
struct ifmap on 32 bit architectures. So do_ioctl_ifconf() assumed a wrong
size of 32 for struct ifreq instead of the correct size of 40 on 64 bit
architectures.

The fix makes do_ioctl_ifconf() handle struct ifmap as the biggest part of
the union, treating struct ifreq with the correct size.

Signed-off-by: Stefan <stefan-guix@vodafonemail.de>
Message-Id: <60AA0765-53DD-43D1-A3D2-75F1778526F6@vodafonemail.de>
Signed-off-by: Laurent Vivier <laurent@vivier.eu>
Diffstat (limited to 'linux-user/syscall.c')
-rw-r--r--linux-user/syscall.c3
1 files changed, 2 insertions, 1 deletions
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index dcb4009e2f..6fea00869e 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -4914,6 +4914,7 @@ static abi_long do_ioctl_ifconf(const IOCTLEntry *ie, uint8_t *buf_temp,
     struct ifconf *host_ifconf;
     uint32_t outbufsz;
     const argtype ifreq_arg_type[] = { MK_STRUCT(STRUCT_sockaddr_ifreq) };
+    const argtype ifreq_max_type[] = { MK_STRUCT(STRUCT_ifmap_ifreq) };
     int target_ifreq_size;
     int nb_ifreq;
     int free_buf = 0;
@@ -4937,7 +4938,7 @@ static abi_long do_ioctl_ifconf(const IOCTLEntry *ie, uint8_t *buf_temp,
 
     host_ifconf = (struct ifconf *)(unsigned long)buf_temp;
     target_ifc_buf = (abi_long)(unsigned long)host_ifconf->ifc_buf;
-    target_ifreq_size = thunk_type_size(ifreq_arg_type, 0);
+    target_ifreq_size = thunk_type_size(ifreq_max_type, 0);
 
     if (target_ifc_buf != 0) {
         target_ifc_len = host_ifconf->ifc_len;