|
Message-ID: <20110807040212.GF132@brightrain.aerifal.cx> Date: Sun, 7 Aug 2011 00:02:12 -0400 From: Rich Felker <dalias@...ifal.cx> To: musl@...ts.openwall.com Subject: close() failure, EINTR, cancellation 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
Powered by blists - more mailing lists
Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.