mailing list of musl libc
 help / color / mirror / code / Atom feed
From: Rich Felker <dalias@aerifal.cx>
To: musl@lists.openwall.com
Subject: close() failure, EINTR, cancellation
Date: Sun, 7 Aug 2011 00:02:12 -0400	[thread overview]
Message-ID: <20110807040212.GF132@brightrain.aerifal.cx> (raw)

I've been following up on the previous thread where Vasiliy Kulikov
and I discussed dangers of close failure, and this is what I've found.
On Linux,

1. The close syscall always deallocates the file descriptor, even if
it "fails". There's never any danger of "leaking" file descriptors
from close failure.

2. As such, the close syscall is not restartable if interrupted by a
signal, because the resource it's operating on was already
deallocated. The kernel takes care to replace ERESTARTSYS etc. with
EINTR before returning to userspace.

3. This means close can fail with EINTR even when signal handlers were
all installed with SA_RESTART.

Hopefully the previously discussed security issue has been laid to
rest by this, but a new issue has been raised: what should pthread
cancellation do to close?

There are two considerations: what does POSIX require, and what's
necessary to write robust applications?

For POSIX conformance, close must check for cancellation at least once
somewhere during the operation, and it must not remain
blocked/sleeping while a cancellation request is pending.

For the latter consideration, an application must always be able to
detect whether the file descriptor was deallocated or not. Otherwise
it will leak a file descriptor (if the application thinks it was
deallocated but it wasn't) or it will wrongly retry closing a file
descriptor that was already closed, possibly closing the wrong file.

The possible behaviors compatible with both requirements are:
1. close always closes the fd, but may never return if cancelled.
2. close is only cancellable before closing the fd, and always returns
if it successfully deallocated the fd.

I don't like option 1 because it's very counter-intuitive (differs
from the usual expectation that cancellation indicates the operation
did not successfully complete) and hard to implement without race
conditions that could lead to uncancellable blocking.

For now I'm going with option 2. It seems like the natural behavior
and it requires only minimal changes (special-casing of SYS_close, the
only syscall that fails with EINTR after succeeding) to musl.

If anyone thinks this sounds wrong, please jump in with ideas.

Rich



                 reply	other threads:[~2011-08-07  4:02 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20110807040212.GF132@brightrain.aerifal.cx \
    --to=dalias@aerifal.cx \
    --cc=musl@lists.openwall.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/musl/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).