From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:58737) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bGNnm-0000ei-V4 for qemu-devel@nongnu.org; Fri, 24 Jun 2016 05:53:32 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1bGNnh-0003Cp-9V for qemu-devel@nongnu.org; Fri, 24 Jun 2016 05:53:29 -0400 Received: from mail-lf0-x232.google.com ([2a00:1450:4010:c07::232]:32877) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bGNnh-0003CK-1d for qemu-devel@nongnu.org; Fri, 24 Jun 2016 05:53:25 -0400 Received: by mail-lf0-x232.google.com with SMTP id f6so112301795lfg.0 for ; Fri, 24 Jun 2016 02:53:24 -0700 (PDT) From: riku.voipio@linaro.org Date: Fri, 24 Jun 2016 12:52:56 +0300 Message-Id: <55d72a7eb32858d50ba0777cfde2027d007010b2.1466760944.git.riku.voipio@linaro.org> In-Reply-To: References: Subject: [Qemu-devel] [PULL 01/24] linux-user: Avoid possible misalignment in host_to_target_siginfo() List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: Peter Maydell From: Peter Maydell host_to_target_siginfo() is implemented by a combination of host_to_target_siginfo_noswap() followed by tswap_siginfo(). The first of these two functions assumes that the target_siginfo_t it is writing to is correctly aligned, but the pointer passed into host_to_target_siginfo() is directly from the guest and might be misaligned. Use a local variable to avoid this problem. (tswap_siginfo() does now correctly handle a misaligned destination.) We have to add a memset() to host_to_target_siginfo_noswap() to avoid some false positive "may be used uninitialized" warnings from gcc about subfields of the _sifields union if it chooses to inline both tswap_siginfo() and host_to_target_siginfo_noswap() into host_to_target_siginfo(). Signed-off-by: Peter Maydell Reviewed-by: Laurent Vivier Signed-off-by: Peter Maydell --- linux-user/signal.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/linux-user/signal.c b/linux-user/signal.c index 1dadddf..e2d55ff 100644 --- a/linux-user/signal.c +++ b/linux-user/signal.c @@ -278,6 +278,14 @@ static inline void host_to_target_siginfo_noswap(target_siginfo_t *tinfo, tinfo->si_errno = 0; tinfo->si_code = info->si_code; + /* This memset serves two purposes: + * (1) ensure we don't leak random junk to the guest later + * (2) placate false positives from gcc about fields + * being used uninitialized if it chooses to inline both this + * function and tswap_siginfo() into host_to_target_siginfo(). + */ + memset(tinfo->_sifields._pad, 0, sizeof(tinfo->_sifields._pad)); + /* This is awkward, because we have to use a combination of * the si_code and si_signo to figure out which of the union's * members are valid. (Within the host kernel it is always possible @@ -397,8 +405,9 @@ static void tswap_siginfo(target_siginfo_t *tinfo, void host_to_target_siginfo(target_siginfo_t *tinfo, const siginfo_t *info) { - host_to_target_siginfo_noswap(tinfo, info); - tswap_siginfo(tinfo, tinfo); + target_siginfo_t tgt_tmp; + host_to_target_siginfo_noswap(&tgt_tmp, info); + tswap_siginfo(tinfo, &tgt_tmp); } /* XXX: we support only POSIX RT signals are used. */ -- 2.1.4