aboutsummaryrefslogtreecommitdiff
path: root/linux-user/errno_defs.h
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2016-05-27 15:51:59 +0100
committerRiku Voipio <riku.voipio@linaro.org>2016-06-07 16:39:08 +0300
commita70dadc7f1a3e96a7179c6c3a6ccd1a0ea65760a (patch)
treee34ceed685ce773412484873c9be584f71c19348 /linux-user/errno_defs.h
parent7d92d34ee4c7988f5ef6c8a5ed23d2c3e0837253 (diff)
linux-user: Use both si_code and si_signo when converting siginfo_t
The siginfo_t struct includes a union. The correct way to identify which fields of the union are relevant is complicated, 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 to tell, but the kernel carefully avoids giving userspace the high 16 bits of si_code, so we don't have the information to do this the easy way...) We therefore make our best guess, bearing in mind that a guest can spoof most of the si_codes via rt_sigqueueinfo() if it likes. Once we have made our guess, we record it in the top 16 bits of the si_code, so that tswap_siginfo() later can use it. tswap_siginfo() then strips these top bits out before writing si_code to the guest (sign-extending the lower bits). This fixes a bug where fields were sometimes wrong; in particular the LTP kill10 test went into an infinite loop because its signal handler got a si_pid value of 0 rather than the pid of the sending process. As part of this change, we switch to using __put_user() in the tswap_siginfo code which writes out the byteswapped values to the target memory, in case the target memory pointer is not sufficiently aligned for the host CPU's requirements. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Riku Voipio <riku.voipio@linaro.org>
Diffstat (limited to 'linux-user/errno_defs.h')
0 files changed, 0 insertions, 0 deletions