Le 13/01/2022 à 10:37, Serge Belyshev a écrit :
When called with WNOHANG and no child has exited, waitid returns with
info.si_pid set to zero and thus check for info.si_pid != 0 will cause
target siginfo structure to be uninitialized. Fixed by removing the check.
Signed-off-by: Serge Belyshev <[email protected]>
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/817
---
linux-user/syscall.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 5950222a77..b80531ac4c 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -8724,9 +8724,8 @@ static abi_long do_syscall1(void *cpu_env, int num,
abi_long arg1,
case TARGET_NR_waitid:
{
siginfo_t info;
- info.si_pid = 0;
ret = get_errno(safe_waitid(arg1, arg2, &info, arg4, NULL));
- if (!is_error(ret) && arg3 && info.si_pid != 0) {
+ if (!is_error(ret) && arg3) {
if (!(p = lock_user(VERIFY_WRITE, arg3,
sizeof(target_siginfo_t), 0)))
return -TARGET_EFAULT;
host_to_target_siginfo(p, &info);
According to wait(2), it sounds a little bit more complicated than that.
If WNOHANG was specified in options and there were no children in a
waitable state, then
waitid() returns 0 immediately and the state of the siginfo_t structure
pointed to by
infop depends on the implementation. To (portably) distinguish
this case from that
where a child was in a waitable state, zero out the si_pid field before
the call and check
for a nonzero value in this field after the call returns.
POSIX.1-2008 Technical Corrigendum 1 (2013) adds the requirement that
when WNOHANG is
specified in options and there were no children in a waitable state,
then waitid() should
zero out the si_pid and si_signo fields of the structure. On Linux and
other implementations
that adhere to this requirement, it is not necessary to zero out the
si_pid field before
calling waitid(). However, not all implementations follow the POSIX.1
specification on
this point.
Perhaps the best approach would be to copy the caller target siginfo to the host one, call host
waitpid(), remove the "info.si_pid != 0" and copy back the host siginfo to target one?
Thanks,
Laurent