summary refs log tree commit diff stats
path: root/linux-user/signal.c
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2016-06-29 10:43:07 +0100
committerPeter Maydell <peter.maydell@linaro.org>2016-06-29 10:43:08 +0100
commit3e904d6ade7f363c64b3c54c5d14372b8a9e6892 (patch)
tree6cffcbf0eac7b0894a39002ae8b76cc8813d248d /linux-user/signal.c
parentd7f30403576f04f1f3a5fb5a1d18cba8dfa7a6d2 (diff)
parent4ba92cd736a9ce0dc83c9b16a75d24d385e1cdf3 (diff)
downloadfocaccia-qemu-3e904d6ade7f363c64b3c54c5d14372b8a9e6892.tar.gz
focaccia-qemu-3e904d6ade7f363c64b3c54c5d14372b8a9e6892.zip
Merge remote-tracking branch 'remotes/riku/tags/pull-linux-user-20160628' into staging
Drop building linux-user targets on HPPA or m68k host systems
and add safe_syscall support for i386, aarch64, arm, ppc64 and
s390x.

# gpg: Signature made Tue 28 Jun 2016 19:31:16 BST
# gpg:                using RSA key 0xB44890DEDE3C9BC0
# gpg: Good signature from "Riku Voipio <riku.voipio@iki.fi>"
# gpg:                 aka "Riku Voipio <riku.voipio@linaro.org>"
# Primary key fingerprint: FF82 03C8 C391 98AE 0581  41EF B448 90DE DE3C 9BC0

* remotes/riku/tags/pull-linux-user-20160628: (24 commits)
  linux-user: Provide safe_syscall for ppc64
  linux-user: Provide safe_syscall for s390x
  linux-user: Provide safe_syscall for aarch64
  linux-user: Provide safe_syscall for arm
  linux-user: Provide safe_syscall for i386
  linux-user: fix x86_64 safe_syscall
  linux-user: don't swap NLMSG_DATA() fields
  linux-user: fd_trans_host_to_target_data() must process only received data
  linux-user: add missing return in netlink switch statement
  linux-user: update get_thread_area/set_thread_area strace
  linux-user: fix clone() strace
  linux-user: add socket() strace
  linux-user: add socketcall() strace
  linux-user: Support F_GETPIPE_SZ and F_SETPIPE_SZ fcntls
  linux-user: Fix wrong type used for argument to rt_sigqueueinfo
  linux-user: Create a hostdep.h for each host architecture
  user-exec: Remove unused code for OSX hosts
  user-exec: Delete now-unused hppa and m68k cpu_signal_handler() code
  configure: Don't allow user-only targets for unknown CPU architectures
  configure: Don't override ARCH=unknown if enabling TCI
  ...

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'linux-user/signal.c')
-rw-r--r--linux-user/signal.c23
1 files changed, 20 insertions, 3 deletions
diff --git a/linux-user/signal.c b/linux-user/signal.c
index 1dadddf2dd..9d980456ec 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. */
@@ -627,8 +636,16 @@ static void host_signal_handler(int host_signum, siginfo_t *info,
      * code in case the guest code provokes one in the window between
      * now and it getting out to the main loop. Signals will be
      * unblocked again in process_pending_signals().
+     *
+     * WARNING: we cannot use sigfillset() here because the uc_sigmask
+     * field is a kernel sigset_t, which is much smaller than the
+     * libc sigset_t which sigfillset() operates on. Using sigfillset()
+     * would write 0xff bytes off the end of the structure and trash
+     * data on the struct.
+     * We can't use sizeof(uc->uc_sigmask) either, because the libc
+     * headers define the struct field with the wrong (too large) type.
      */
-    sigfillset(&uc->uc_sigmask);
+    memset(&uc->uc_sigmask, 0xff, SIGSET_T_SIZE);
     sigdelset(&uc->uc_sigmask, SIGSEGV);
     sigdelset(&uc->uc_sigmask, SIGBUS);