From 24894f39c677a3fd28d0868010a0d50639d49095 Mon Sep 17 00:00:00 2001 From: Andreas Schwab Date: Tue, 12 Feb 2019 17:34:35 +0100 Subject: [PATCH 1/9] linux-user: fix recvmsg emulation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Set msg_flags in the returned struct msghdr. Signed-off-by: Andreas Schwab Reviewed-by: Laurent Vivier Reviewed-by: Philippe Mathieu-Daudé Message-Id: Signed-off-by: Laurent Vivier --- linux-user/syscall.c | 1 + 1 file changed, 1 insertion(+) diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 5bbb72f3d5..f380048cbd 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -2759,6 +2759,7 @@ static abi_long do_sendrecvmsg_locked(int fd, struct target_msghdr *msgp, } if (!is_error(ret)) { msgp->msg_namelen = tswap32(msg.msg_namelen); + msgp->msg_flags = tswap32(msg.msg_flags); if (msg.msg_name != NULL && msg.msg_name != (void *)-1) { ret = host_to_target_sockaddr(tswapal(msgp->msg_name), msg.msg_name, msg.msg_namelen); From 13ec4ec3e11c80bed9409c7046574d739d277ae3 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Mon, 11 Feb 2019 23:48:39 -0800 Subject: [PATCH 2/9] linux-user: Add ELF_PLATFORM for arm The 32-bit kernel has strings for v4, v5, v6, v7, v7m. The 64-bit kernel, in compat mode, has strings for v8. Fixes: https://bugs.launchpad.net/bugs/1813034 Signed-off-by: Richard Henderson Reviewed-by: Laurent Vivier Message-Id: <20190212074840.13542-2-richard.henderson@linaro.org> Signed-off-by: Laurent Vivier --- linux-user/elfload.c | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/linux-user/elfload.c b/linux-user/elfload.c index 6e8762b40d..940a97a2f2 100644 --- a/linux-user/elfload.c +++ b/linux-user/elfload.c @@ -500,6 +500,37 @@ static uint32_t get_elf_hwcap2(void) #undef GET_FEATURE #undef GET_FEATURE_ID +#define ELF_PLATFORM get_elf_platform() + +static const char *get_elf_platform(void) +{ + CPUARMState *env = thread_cpu->env_ptr; + +#ifdef TARGET_WORDS_BIGENDIAN +# define END "b" +#else +# define END "l" +#endif + + if (arm_feature(env, ARM_FEATURE_V8)) { + return "v8" END; + } else if (arm_feature(env, ARM_FEATURE_V7)) { + if (arm_feature(env, ARM_FEATURE_M)) { + return "v7m" END; + } else { + return "v7" END; + } + } else if (arm_feature(env, ARM_FEATURE_V6)) { + return "v6" END; + } else if (arm_feature(env, ARM_FEATURE_V5)) { + return "v5" END; + } else { + return "v4" END; + } + +#undef END +} + #else /* 64 bit ARM definitions */ #define ELF_START_MMAP 0x80000000 From e20e3ec928ebdcad051ed3ac71ccf46a5aacc59b Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Mon, 11 Feb 2019 23:48:40 -0800 Subject: [PATCH 3/9] linux-user: Fix ELF_PLATFORM for aarch64_be-linux-user Signed-off-by: Richard Henderson Reviewed-by: Laurent Vivier Message-Id: <20190212074840.13542-3-richard.henderson@linaro.org> Signed-off-by: Laurent Vivier --- linux-user/elfload.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/linux-user/elfload.c b/linux-user/elfload.c index 940a97a2f2..c1a26021f8 100644 --- a/linux-user/elfload.c +++ b/linux-user/elfload.c @@ -537,7 +537,11 @@ static const char *get_elf_platform(void) #define ELF_ARCH EM_AARCH64 #define ELF_CLASS ELFCLASS64 -#define ELF_PLATFORM "aarch64" +#ifdef TARGET_WORDS_BIGENDIAN +# define ELF_PLATFORM "aarch64_be" +#else +# define ELF_PLATFORM "aarch64" +#endif static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop) From cd8133679f7e0e2c292f631f1c78b2452d2435c7 Mon Sep 17 00:00:00 2001 From: Andreas Schwab Date: Thu, 14 Feb 2019 12:43:40 +0100 Subject: [PATCH 4/9] linux-user: fix emulation of accept4/getpeername/getsockname/recvfrom syscalls System calls that return a socket address do so by writing the (possibly truncated) address into the provided buffer space, but setting the addrlen parameter to the actual size of the address. To determine how much to copy back to the target memory the emulation needs to remember the incoming value of the addrlen parameter, so that it doesn't write past the buffer limits. Signed-off-by: Andreas Schwab Reviewed-by: Laurent Vivier Message-Id: Signed-off-by: Laurent Vivier --- linux-user/syscall.c | 41 +++++++++++++++++++++++++---------------- 1 file changed, 25 insertions(+), 16 deletions(-) diff --git a/linux-user/syscall.c b/linux-user/syscall.c index f380048cbd..5f72209deb 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -2847,7 +2847,7 @@ static abi_long do_sendrecvmmsg(int fd, abi_ulong target_msgvec, static abi_long do_accept4(int fd, abi_ulong target_addr, abi_ulong target_addrlen_addr, int flags) { - socklen_t addrlen; + socklen_t addrlen, ret_addrlen; void *addr; abi_long ret; int host_flags; @@ -2871,11 +2871,13 @@ static abi_long do_accept4(int fd, abi_ulong target_addr, addr = alloca(addrlen); - ret = get_errno(safe_accept4(fd, addr, &addrlen, host_flags)); + ret_addrlen = addrlen; + ret = get_errno(safe_accept4(fd, addr, &ret_addrlen, host_flags)); if (!is_error(ret)) { - host_to_target_sockaddr(target_addr, addr, addrlen); - if (put_user_u32(addrlen, target_addrlen_addr)) + host_to_target_sockaddr(target_addr, addr, MIN(addrlen, ret_addrlen)); + if (put_user_u32(ret_addrlen, target_addrlen_addr)) { ret = -TARGET_EFAULT; + } } return ret; } @@ -2884,7 +2886,7 @@ static abi_long do_accept4(int fd, abi_ulong target_addr, static abi_long do_getpeername(int fd, abi_ulong target_addr, abi_ulong target_addrlen_addr) { - socklen_t addrlen; + socklen_t addrlen, ret_addrlen; void *addr; abi_long ret; @@ -2900,11 +2902,13 @@ static abi_long do_getpeername(int fd, abi_ulong target_addr, addr = alloca(addrlen); - ret = get_errno(getpeername(fd, addr, &addrlen)); + ret_addrlen = addrlen; + ret = get_errno(getpeername(fd, addr, &ret_addrlen)); if (!is_error(ret)) { - host_to_target_sockaddr(target_addr, addr, addrlen); - if (put_user_u32(addrlen, target_addrlen_addr)) + host_to_target_sockaddr(target_addr, addr, MIN(addrlen, ret_addrlen)); + if (put_user_u32(ret_addrlen, target_addrlen_addr)) { ret = -TARGET_EFAULT; + } } return ret; } @@ -2913,7 +2917,7 @@ static abi_long do_getpeername(int fd, abi_ulong target_addr, static abi_long do_getsockname(int fd, abi_ulong target_addr, abi_ulong target_addrlen_addr) { - socklen_t addrlen; + socklen_t addrlen, ret_addrlen; void *addr; abi_long ret; @@ -2929,11 +2933,13 @@ static abi_long do_getsockname(int fd, abi_ulong target_addr, addr = alloca(addrlen); - ret = get_errno(getsockname(fd, addr, &addrlen)); + ret_addrlen = addrlen; + ret = get_errno(getsockname(fd, addr, &ret_addrlen)); if (!is_error(ret)) { - host_to_target_sockaddr(target_addr, addr, addrlen); - if (put_user_u32(addrlen, target_addrlen_addr)) + host_to_target_sockaddr(target_addr, addr, MIN(addrlen, ret_addrlen)); + if (put_user_u32(ret_addrlen, target_addrlen_addr)) { ret = -TARGET_EFAULT; + } } return ret; } @@ -3005,7 +3011,7 @@ static abi_long do_recvfrom(int fd, abi_ulong msg, size_t len, int flags, abi_ulong target_addr, abi_ulong target_addrlen) { - socklen_t addrlen; + socklen_t addrlen, ret_addrlen; void *addr; void *host_msg; abi_long ret; @@ -3023,10 +3029,12 @@ static abi_long do_recvfrom(int fd, abi_ulong msg, size_t len, int flags, goto fail; } addr = alloca(addrlen); + ret_addrlen = addrlen; ret = get_errno(safe_recvfrom(fd, host_msg, len, flags, - addr, &addrlen)); + addr, &ret_addrlen)); } else { addr = NULL; /* To keep compiler quiet. */ + addrlen = 0; /* To keep compiler quiet. */ ret = get_errno(safe_recvfrom(fd, host_msg, len, flags, NULL, 0)); } if (!is_error(ret)) { @@ -3039,8 +3047,9 @@ static abi_long do_recvfrom(int fd, abi_ulong msg, size_t len, int flags, } } if (target_addr) { - host_to_target_sockaddr(target_addr, addr, addrlen); - if (put_user_u32(addrlen, target_addrlen)) { + host_to_target_sockaddr(target_addr, addr, + MIN(addrlen, ret_addrlen)); + if (put_user_u32(ret_addrlen, target_addrlen)) { ret = -TARGET_EFAULT; goto fail; } From 14c8a3a157b437e54fbe097d991dca86ac828a14 Mon Sep 17 00:00:00 2001 From: Sandra Loosemore Date: Wed, 13 Feb 2019 09:50:26 -0700 Subject: [PATCH 5/9] Fix breakpoint support in Nios II user-mode emulation. Nios II user-mode emulation was missing handling for EXCP_DEBUG, making the gdb stub essentially useless. This patch adds the missing piece. The new code was copied from the existing EXCP_TRAP handling and is also similar to what other targets (e.g., arm) do with EXCP_DEBUG. Signed-off-by: Sandra Loosemore Reviewed-by: Peter Maydell Message-Id: <1550076626-7202-1-git-send-email-sandra@codesourcery.com> Signed-off-by: Laurent Vivier --- linux-user/nios2/cpu_loop.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/linux-user/nios2/cpu_loop.c b/linux-user/nios2/cpu_loop.c index b96b1aa119..5aa1eca740 100644 --- a/linux-user/nios2/cpu_loop.c +++ b/linux-user/nios2/cpu_loop.c @@ -73,6 +73,12 @@ void cpu_loop(CPUNios2State *env) queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info); break; } + case EXCP_DEBUG: + info.si_signo = TARGET_SIGTRAP; + info.si_errno = 0; + info.si_code = TARGET_TRAP_BRKPT; + queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info); + break; case 0xaa: switch (env->regs[R_PC]) { /*case 0x1000:*/ /* TODO:__kuser_helper_version */ From ba584f1de30e58b0d93cd81bd437271b894eefbf Mon Sep 17 00:00:00 2001 From: Andreas Schwab Date: Tue, 5 Mar 2019 17:45:05 +0100 Subject: [PATCH 6/9] linux-user: don't short-circuit read with zero length A zero-length read still needs to do the usual checks, thus it may return errors like EBADF. This makes the read syscall emulation consistent with the pread64 syscall emulation. Signed-off-by: Andreas Schwab Reviewed-by: Laurent Vivier Message-Id: Signed-off-by: Laurent Vivier --- linux-user/syscall.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 5f72209deb..9f7eb7d7a8 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -7009,8 +7009,8 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1, _exit(arg1); return 0; /* avoid warning */ case TARGET_NR_read: - if (arg3 == 0) { - return 0; + if (arg2 == 0 && arg3 == 0) { + return get_errno(safe_read(arg1, 0, 0)); } else { if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0))) return -TARGET_EFAULT; From b78c522ab949582b5e580e15d6ebf979845ccc94 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= Date: Tue, 5 Mar 2019 16:15:00 +0100 Subject: [PATCH 7/9] linux-user: fix "may be used uninitialized" warnings MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes: /home/elmarco/src/qemu/linux-user/syscall.c: In function ‘do_ioctl_rt’: /home/elmarco/src/qemu/linux-user/syscall.c:4773:9: error: ‘host_rt_dev_ptr’ may be used uninitialized in this function [-Werror=maybe-uninitialized] if (*host_rt_dev_ptr != 0) { ^~~~~~~~~~~~~~~~ /home/elmarco/src/qemu/linux-user/syscall.c:4774:9: error: ‘target_rt_dev_ptr’ may be used uninitialized in this function [-Werror=maybe-uninitialized] unlock_user((void *)*host_rt_dev_ptr, ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ *target_rt_dev_ptr, 0); ~~~~~~~~~~~~~~~~~~~~~~ Based on previous discussion from patch "linux-users/syscall: make do_ioctl_rt safer" by Alex Bennée. Signed-off-by: Marc-André Lureau Reviewed-by: Laurent Vivier Message-Id: <20190305151500.25038-1-marcandre.lureau@redhat.com> Signed-off-by: Laurent Vivier --- linux-user/syscall.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 9f7eb7d7a8..208fd1813d 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -4733,8 +4733,8 @@ static abi_long do_ioctl_rt(const IOCTLEntry *ie, uint8_t *buf_temp, const int *dst_offsets, *src_offsets; int target_size; void *argptr; - abi_ulong *target_rt_dev_ptr; - unsigned long *host_rt_dev_ptr; + abi_ulong *target_rt_dev_ptr = NULL; + unsigned long *host_rt_dev_ptr = NULL; abi_long ret; int i; @@ -4780,6 +4780,9 @@ static abi_long do_ioctl_rt(const IOCTLEntry *ie, uint8_t *buf_temp, unlock_user(argptr, arg, 0); ret = get_errno(safe_ioctl(fd, ie->host_cmd, buf_temp)); + + assert(host_rt_dev_ptr != NULL); + assert(target_rt_dev_ptr != NULL); if (*host_rt_dev_ptr != 0) { unlock_user((void *)*host_rt_dev_ptr, *target_rt_dev_ptr, 0); From 1b7695fe5f4efa5901c560c8f90ee5f3429ee843 Mon Sep 17 00:00:00 2001 From: Helge Deller Date: Wed, 27 Feb 2019 20:11:15 +0100 Subject: [PATCH 8/9] linux-user: Nicer strace output of chroot() syscall Signed-off-by: Helge Deller Reviewed-by: Laurent Vivier Message-Id: <20190227191115.GA20163@ls3530.dellerweb.de> Signed-off-by: Laurent Vivier --- linux-user/strace.c | 12 ++++++++++++ linux-user/strace.list | 2 +- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/linux-user/strace.c b/linux-user/strace.c index 7318392e57..6f72a74c09 100644 --- a/linux-user/strace.c +++ b/linux-user/strace.c @@ -1235,6 +1235,18 @@ print_chdir(const struct syscallname *name, } #endif +#ifdef TARGET_NR_chroot +static void +print_chroot(const struct syscallname *name, + abi_long arg0, abi_long arg1, abi_long arg2, + abi_long arg3, abi_long arg4, abi_long arg5) +{ + print_syscall_prologue(name); + print_string(arg0, 1); + print_syscall_epilogue(name); +} +#endif + #ifdef TARGET_NR_chmod static void print_chmod(const struct syscallname *name, diff --git a/linux-user/strace.list b/linux-user/strace.list index ff8bb19f5f..db21ce4177 100644 --- a/linux-user/strace.list +++ b/linux-user/strace.list @@ -77,7 +77,7 @@ { TARGET_NR_chown32, "chown32" , NULL, NULL, NULL }, #endif #ifdef TARGET_NR_chroot -{ TARGET_NR_chroot, "chroot" , NULL, NULL, NULL }, +{ TARGET_NR_chroot, "chroot" , NULL, print_chroot, NULL }, #endif #ifdef TARGET_NR_clock_adjtime { TARGET_NR_clock_adjtime, "clock_adjtime" , NULL, print_clock_adjtime, NULL }, From 61b463fbf6cbf21fcd9abb5af765a19b88dbc1ba Mon Sep 17 00:00:00 2001 From: Laurent Vivier Date: Wed, 6 Mar 2019 21:09:25 +0100 Subject: [PATCH 9/9] linux-user: add new netlink types MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add QEMU_IFLA_BR_VLAN_STATS_PER_PORT (from linux v4.20), QEMU_IFLA_BR_MULTI_BOOLOPT (from linux v5.0). The first new entry fixes the following error: Unknown QEMU_IFLA_BR type 45 Signed-off-by: Laurent Vivier Reviewed-by: Philippe Mathieu-Daudé Message-Id: <20190306200925.17605-1-laurent@vivier.eu> Signed-off-by: Laurent Vivier --- linux-user/fd-trans.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/linux-user/fd-trans.c b/linux-user/fd-trans.c index 30425c9df6..612819c1b1 100644 --- a/linux-user/fd-trans.c +++ b/linux-user/fd-trans.c @@ -75,6 +75,8 @@ enum { QEMU_IFLA_BR_MCAST_STATS_ENABLED, QEMU_IFLA_BR_MCAST_IGMP_VERSION, QEMU_IFLA_BR_MCAST_MLD_VERSION, + QEMU_IFLA_BR_VLAN_STATS_PER_PORT, + QEMU_IFLA_BR_MULTI_BOOLOPT, QEMU___IFLA_BR_MAX, }; @@ -438,6 +440,7 @@ static abi_long host_to_target_data_bridge_nlattr(struct nlattr *nlattr, case QEMU_IFLA_BR_MCAST_STATS_ENABLED: case QEMU_IFLA_BR_MCAST_IGMP_VERSION: case QEMU_IFLA_BR_MCAST_MLD_VERSION: + case QEMU_IFLA_BR_VLAN_STATS_PER_PORT: break; /* uint16_t */ case QEMU_IFLA_BR_PRIORITY: @@ -543,6 +546,12 @@ static abi_long host_to_target_slave_data_bridge_nlattr(struct nlattr *nlattr, case QEMU_IFLA_BRPORT_ROOT_ID: case QEMU_IFLA_BRPORT_BRIDGE_ID: break; + /* br_boolopt_multi { uint32_t, uint32_t } */ + case QEMU_IFLA_BR_MULTI_BOOLOPT: + u32 = NLA_DATA(nlattr); + u32[0] = tswap32(u32[0]); /* optval */ + u32[1] = tswap32(u32[1]); /* optmask */ + break; default: gemu_log("Unknown QEMU_IFLA_BRPORT type %d\n", nlattr->nla_type); break;