lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20100825.153424.246521475.davem@davemloft.net>
Date:	Wed, 25 Aug 2010 15:34:24 -0700 (PDT)
From:	David Miller <davem@...emloft.net>
To:	kosaki.motohiro@...fujitsu.com
Cc:	netdev@...r.kernel.org, linux-kernel@...r.kernel.org,
	yoshfuji@...ux-ipv6.org
Subject: Re: [PATCH] tcp: select(writefds) don't hang up when a peer close
 connection

From: KOSAKI Motohiro <kosaki.motohiro@...fujitsu.com>
Date: Wed, 25 Aug 2010 11:05:48 +0900 (JST)

> This issue come from ruby language community. Below test program
> hang up when only run on Linux.
> 
> 	% uname -mrsv
> 	Linux 2.6.26-2-486 #1 Sat Dec 26 08:37:39 UTC 2009 i686
> 	% ruby -rsocket -ve '
> 	BasicSocket.do_not_reverse_lookup = true
> 	serv = TCPServer.open("127.0.0.1", 0)
> 	s1 = TCPSocket.open("127.0.0.1", serv.addr[1])
> 	s2 = serv.accept
> 	s2.close
> 	s1.write("a") rescue p $!
> 	s1.write("a") rescue p $!
> 	Thread.new {
> 	  s1.write("a")
> 	}.join'
> 	ruby 1.9.3dev (2010-07-06 trunk 28554) [i686-linux]
> 	#<Errno::EPIPE: Broken pipe>
> 	[Hang Here]
> 
> FreeBSD, Solaris, Mac doesn't. because Ruby's write() method call
> select() internally. and tcp_poll has a bug.

In your opinion.

> SUS defined 'ready for writing' of select() as following.
> 
> |  A descriptor shall be considered ready for writing when a call to an output
> |  function with O_NONBLOCK clear would not block, whether or not the function
> |  would transfer data successfully.
> 
> That said, EPIPE situation is clearly one of 'ready for writing'.

How Linux should behave is defined by many things, and often it is
simply defined by how we've behaved for a very long time.  This is
because changing behavior can often break as many applications as it
can fix.  Standards don't necessarily tell us how we must behave,
since often is it impractical to follow their definions.

And in this case here, I call into question the behavior of Ruby and
the application from two perspectives:

1) Unlike all of the other conditions signalled by poll() this is
   one the application explicitly created and therefore knows about.

   If the application calls close() or shutdown() with the send flag
   set, IT KNOWS what is going to happen on a write() attempt.

2) Ruby and this script will have to deal with the past 13 years
   worth of Linux kernels.  Even if I were to apply this fix now
   it is not going to propagate onto a user's system any time soon.

   Many systems would never ever get this fix.

   Therefore it behooves Ruby and this script to make a very reasonable
   change, which is to track when close() or send shutdown() calls occur
   and behave appropriately on a write() call.

I'm therefore not applying this patch, because not only can applications
handle this properly with information they already have, the change has
the potential to break applications.
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ