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: <201510211604.t9LG4r9A005345@room101.nl.oracle.com>
Date:	Wed, 21 Oct 2015 18:04:53 +0200
From:	Casper.Dik@...cle.com
To:	David Miller <davem@...emloft.net>
cc:	Alan.Burlison@...cle.com, viro@...IV.linux.org.uk,
	eric.dumazet@...il.com, stephen@...workplumber.org,
	netdev@...r.kernel.org, dholland-tech@...bsd.org
Subject: Re: [Bug 106241] New: shutdown(3)/close(3) behaviour is incorrect for sockets in accept(3) 


From: David Miller <davem@...emloft.net>
Date: Wed, 21 Oct 2015 08:30:08 -0700 (PDT) (17:30 CEST)

>From: Alan Burlison <Alan.Burlison@...cle.com>
>Date: Wed, 21 Oct 2015 15:38:51 +0100
>
>> While this algorithm is pretty expensive, it is not often invoked.
>
>I bet it can be easily intentionally invoked, by a malicious entity no
>less.

It is only expensive within the process itself.  Whether it is run inside 
the kernel isn't much different in the context of Solaris.  If you have an 
attacker which can run any code, it doesn't really matter what that code 
is.  It is not really, expensive (like grabbing expensive locks or
for any length of time).  It's basically O(n) depending on the numbers of 
threads in the process.

If you have an application which can be triggered in doing that, it is 
still a bug in the application.  

Is such socket still listed with netstat on Linux?  I believe it uses
uses /proc and it will not be able to find that socket through the list of 
opened files.

If we look at our typical problem we have a accept loop:

		for (;;) {
			newfd = accept(fd. ...);  /* X */

			/* stuff */
		}

While we have a second thread doing a "close(fd);" and possibly opening 
another file which just happens to return this particular fd.

In Solaris the following one of the following things will happen,
whatever the first thread is doing once close() is called:

	- accept() dies with EBADF (close() before or during the call to
	  accept())
	- accept() returns some other error (new fd you can't accept on)
	- accept() returns a new fd (if it was closed and reopened and a 
	  the new fd allows accept())

On Linux exactly the same thing happens *except* when we find ourselves in accept(),
then we wait until a connection made or "shutdown()" is called.

I don't think any of the outcomes in the first thread is acceptable; 
clearly no sufficient synchronization between the threads.


At that point Linux cannot find out who owns the socket:

#  netstat -p -a | grep /tmp/unix
unix  2      [ ACC ]     STREAM     LISTENING     14743  -                   /tmp/unix_sock

In Solaris you'd get:

netstat -u -f unix| grep unix_
stream-ord casper     5334 shutdown       /tmp/unix_sock

Simple synchronization is can be done.

Casper

--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ