netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Al Viro <viro@ftp.linux.org.uk>
To: Stephen Hemminger <shemminger@linux-foundation.org>
Cc: "David S. Miller" <davem@davemloft.net>, netdev@vger.kernel.org
Subject: Re: Files, sockets, and closing
Date: Fri, 26 Oct 2007 23:46:22 +0100	[thread overview]
Message-ID: <20071026224622.GH8181@ftp.linux.org.uk> (raw)
In-Reply-To: <20071026150901.3b7fa6a3@freepuppy.rosehill>

On Fri, Oct 26, 2007 at 03:09:01PM -0700, Stephen Hemminger wrote:

> > close() from another thread is not a way to abort blocked accept().  Never
> > promised to be that.  Just as close() from another thread is not a way to
> > abort blocked write() or read() or sendmsg() or...
> 
> The problem is the Linux interpretation conflicts with the expectation
> of applications that run on other Unix systems.  Most likely, it is
> one of those corner cases not covered by SUS or Posix specs otherwise
> it would have come up earlier. The existing Linux behavior works fine
> it just isn't expected (or well documented).
> 
> I'm fine with just closing the bug (which is what I did initially), but
> where should this get documented?

close(2), perhaps?  "System call on opened file holds a reference to
opened file regardless of what happens to descriptor originally passed
to it" or something to the same effect...

That's what really happens - you get the same effect as if there had been
an additional temporary opened descriptor for that sucker.  And really,
multithreaded application that has one thread rip descriptors from under
another should be damn careful on _any_ system.  Anything that goes
"I've got -EBADF, guess another thread had removed that descriptor,
got to recover" is insane - in effect, it calls accept() blindly and
hopes that race will play out nicely, without hitting
	* thread A calls accept(3)
	* thread B calls close()
	* thread B calls e.g. dup() for unrelated reason and gets the same
descriptor reused
	* thread A finally gets from libc to accept(2), sees no EBADF and
proceeds with accept() on completely unrelated socket, with no indication of
the problem (or returns giving you a bogus errno, depending on what the
hell that descriptor happens to be).

IOW, if you rely on -EBADF to deal with such (userland) races, you are
extremely likely to be screwed.  On Linux, on FreeBSD, on Solaris, whatever.
In very controlled circumstances you might get away with that, but it's
almost certainly a Very Bad Idea(tm).

The bottom line: if descriptor table is a shared resource in your
multithreaded program, treat it as such.  Kernel will survive having
descriptors closed in the middle of syscall just fine; your userland
code is a different story.

  reply	other threads:[~2007-10-26 22:46 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-10-26 21:03 Files, sockets, and closing Stephen Hemminger
2007-10-26 21:45 ` Al Viro
2007-10-26 22:09   ` Stephen Hemminger
2007-10-26 22:46     ` Al Viro [this message]
2007-10-27 18:03 ` Andi Kleen

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=20071026224622.GH8181@ftp.linux.org.uk \
    --to=viro@ftp.linux.org.uk \
    --cc=davem@davemloft.net \
    --cc=netdev@vger.kernel.org \
    --cc=shemminger@linux-foundation.org \
    /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.
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).