This is the mail archive of the glibc-bugs@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug nptl/12683] Race conditions in pthread cancellation


https://sourceware.org/bugzilla/show_bug.cgi?id=12683

--- Comment #14 from Rich Felker <bugdal at aerifal dot cx> ---
>From XSH 2.9.5 Thread Cancellation:

"The side-effects of acting upon a cancellation request while suspended during
a call of a function are the same as the side-effects that may be seen in a
single-threaded program when a call to a function is interrupted by a signal
and the given function returns [EINTR]. Any such side-effects occur before any
cancellation cleanup handlers are called."

This is the important paragraph. By requiring that the side-effects on
cancellation match the side effects on EINTR, the standard requires that
cancellation cannot be acted upon if other irreversible side effects have
already taken place. For example, if a file descriptor has been closed, data
transferred, etc. then cancellation can't happen. The following paragraph
explains further:

"Whenever a thread has cancelability enabled and a cancellation request has
been made with that thread as the target, and the thread then calls any
function that is a cancellation point (such as pthread_testcancel() or read()),
the cancellation request shall be acted upon before the function returns."

This is simple. If cancellation is already pending when a cancellation point is
called, it must be acted upon. The next part is less clear:

"If a thread has cancelability enabled and a cancellation request is made with
the thread as a target while the thread is suspended at a cancellation point,
the thread shall be awakened and the cancellation request shall be acted upon.
It is unspecified whether the cancellation request is acted upon or whether the
cancellation request remains pending and the thread resumes normal execution
if:

* The thread is suspended at a cancellation point and the event for which it is
waiting occurs

* A specified timeout expired

before the cancellation request is acted upon."

This is covering the case of blocking syscalls. If a cancellation request
arrives during a blocking syscall, it's normally acted upon, but there's one
race condition being described: it's possible that the "event being waited for"
arrives just before the cancellation request arrives, but before the target
thread unblocks. In this case, it's implementation-defined whether cancellation
is acted upon (in which case, by the first paragraph, the event remains
pending) or the event is acted upon (in which case the cancellation request
remains pending). The reason for there being two bullet points above is that
some blocking syscalls wait for either an event or a timeout (think of
sem_timedwait or recv with a timeout set by setsockopt), and in that case, the
timeout can also be 'consumed' and cause the cancellation to remain pending.

Anyway, this race condition is the whole matter at hand here. The two
possibilities allowed (again, due to the limitations imposed by the first
paragrah) are acting on the event while leaving cancellation pending, or acting
on cancellation while leaving the event pending. But glibc also has a race
window where it can act on both the event, producing side effects (because the
kernel already has), and act on cancellation. This makes it non-conforming and
makes it impossible to use cancellation safely.

-- 
You are receiving this mail because:
You are on the CC list for the bug.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]