qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [PATCH 1/4] linux-user: add pselect syscall


From: Jamie Lokier
Subject: Re: [Qemu-devel] [PATCH 1/4] linux-user: add pselect syscall
Date: Sun, 28 Mar 2010 19:49:50 +0100
User-agent: Mutt/1.5.13 (2006-08-11)

Paul Brook wrote:
> >This patch adds support for the pselect syscall in linux-user emulation
> >and also adds several support functions required to translate the
> >timespec structs between the target and the host.
> 
> IIUC the whole point of the pselect is that it should be atomic. By
> emulating this in a non-atomic fasion I think you're re-introducing
> the race condition that it is designed to avoid.
>
> Wouldn't it be better to just return ENOSYS and let the guest deal with the 
> problem?

Imho, it's very important to return ENOSYS if the atomic behaviour is
not provided.

The patch actually calls the host's pselect() - it looks almost ok...

But actually, host's pselect() may be Glibc or some other equally
buggy libc, which "emulates" pselect wrongly.  FreeBSD's pselect has
the same problem going back years - with a very recent patch to
support it in the kernel.  It's not just Glibc.

Careful apps detect and avoid libc's bug by calling the pselect syscall
directly.  If it returns ENOSYS, they just use a different (but
slightly slower) race-free technique, or abort - at least they don't
have a quiet corruption bug.

But here we're providing the kernel syscall to guest apps.  There's no
way for them to detect if it's really atomic or not.  And the ones
written carefully to avoid buggy libc will wrongly use it, because
they think it's a kernel call.

I think it's really important we don't pass on libc's buggy behaviour
to the emulated kernel interface, to even break careful apps.

Solution, Riku: Instead of calling pselect(...), qemu should call
syscall(SYS_pselect, ...), with a comment like:

    /*
     * Glibc and some other libcs unhelpfully "emulate" pselect()
     * using select() when the real system call isn't available, and
     * break the atomic guarantee which is the entire point of
     * pselect().  To avoid these libc bugs, go straight to the host
     * kernel using syscall().  If the host kernel doesn't support
     * pselect() it will return ENOSYS, which is what we want to
     * return to the guest.
     */

There might need to be some header file included to get syscall() and
SYS_pselect, which sometimes has other names like NR_pselect.  And
unfortunately the call arguments aren't quite the same, at least on
Linux.

Same goes for ppoll() if that is ever added.

-- Jamie




reply via email to

[Prev in Thread] Current Thread [Next in Thread]