[<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