From mboxrd@z Thu Jan 1 00:00:00 1970 X-Msuck: nntp://news.gmane.org/gmane.linux.lib.musl.general/345 Path: news.gmane.org!not-for-mail From: Rich Felker Newsgroups: gmane.linux.lib.musl.general Subject: close() failure, EINTR, cancellation Date: Sun, 7 Aug 2011 00:02:12 -0400 Message-ID: <20110807040212.GF132@brightrain.aerifal.cx> Reply-To: musl@lists.openwall.com NNTP-Posting-Host: lo.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-Trace: dough.gmane.org 1312690487 6464 80.91.229.12 (7 Aug 2011 04:14:47 GMT) X-Complaints-To: usenet@dough.gmane.org NNTP-Posting-Date: Sun, 7 Aug 2011 04:14:47 +0000 (UTC) To: musl@lists.openwall.com Original-X-From: musl-return-346-gllmg-musl=m.gmane.org@lists.openwall.com Sun Aug 07 06:14:43 2011 Return-path: Envelope-to: gllmg-musl@lo.gmane.org Original-Received: from mother.openwall.net ([195.42.179.200]) by lo.gmane.org with smtp (Exim 4.69) (envelope-from ) id 1Qpul8-0004To-Rz for gllmg-musl@lo.gmane.org; Sun, 07 Aug 2011 06:14:42 +0200 Original-Received: (qmail 24204 invoked by uid 550); 7 Aug 2011 04:14:42 -0000 Mailing-List: contact musl-help@lists.openwall.com; run by ezmlm Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: Original-Received: (qmail 24196 invoked from network); 7 Aug 2011 04:14:42 -0000 Content-Disposition: inline User-Agent: Mutt/1.5.21 (2010-09-15) Xref: news.gmane.org gmane.linux.lib.musl.general:345 Archived-At: 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