[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <e9e755abf80f4fb78f6be494b0529347@AcuMS.aculab.com>
Date: Fri, 21 Feb 2020 10:46:42 +0000
From: David Laight <David.Laight@...LAB.COM>
To: 'Kuniyuki Iwashima' <kuniyu@...zon.co.jp>
CC: "davem@...emloft.net" <davem@...emloft.net>,
"edumazet@...gle.com" <edumazet@...gle.com>,
"kuni1840@...il.com" <kuni1840@...il.com>,
"kuznet@....inr.ac.ru" <kuznet@....inr.ac.ru>,
"netdev@...r.kernel.org" <netdev@...r.kernel.org>,
"osa-contribution-log@...zon.com" <osa-contribution-log@...zon.com>,
"yoshfuji@...ux-ipv6.org" <yoshfuji@...ux-ipv6.org>
Subject: RE: [PATCH net-next 0/3] Improve bind(addr, 0) behaviour.
From: Kuniyuki Iwashima
> Sent: 21 February 2020 10:02
>
> From: David Laight <David.Laight@...LAB.COM>
> Date: Thu, 20 Feb 2020 17:11:46 +0000
> > From: Kuniyuki Iwashima
> > > Sent: 20 February 2020 15:20
> > >
> > > Currently we fail to bind sockets to ephemeral ports when all of the ports
> > > are exhausted even if all sockets have SO_REUSEADDR enabled. In this case,
> > > we still have a chance to connect to the different remote hosts.
> > >
> > > The second and third patches fix the behaviour to fully utilize all space
> > > of the local (addr, port) tuples.
> >
> > Would it make sense to only do this for the implicit bind() done
> > when connect() is called on an unbound socket?
> > In that case only the quadruplet of the local and remote addresses
> > needs to be unique.
>
> The function to reserve a epehemral port is different between bind() and
> connect().
>
> bind : inet_csk_find_open_port
> connect : __inet_hash_connect
>
> The connect() cannot use ports which are consumed by bind()
> because __inet_hash_connect() fails to get a port if tb->fastreuse or
> or tb->fastreuseport is not -1, which only __inet_hash_connect() sets.
> On the other hand, bind() can use ports which are used by connect().
Fixing that asymmetry may make more sense.
Since the final state can already exist.
No need for SO_REUSADDR to be checked at all.
> Moreover, we can call bind() before connect() to decide which IP to use.
> By setting IP_BIND_ADDRESS_NO_PORT to socket, we can defer getting a port
> until connect() is called. However, this means that getting port
> is done by __inet_hash_connect, so that connect() may fail to get a local
> port if it is reserved by bind(). So if we want to reuse ports consumed by
> bind(), we have to call bind() to get ports.
>
> Without this patch, we may fail to get a ephemeral port and to fail to
> bind() in such case we should be able to reuse a local port when connecting
> to remote hosts.
I suspect that opens some security holes.
There is nothing to stop you trying to call listen() (etc).
SO_REUSADDR is pretty limited (for good reason).
I normally set it on listening sockets so that the daemon can be
restarted while old connections are lurking (usually in a FIN_WAIT state).
But even that probably opens some 'holes'.
You really don't want to be allocating an ephemeral port before connect().
I'm pretty sure you can't 'unconnect' a socket leaving is bound (and usable).
David
-
Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK
Registration No: 1397386 (Wales)
Powered by blists - more mailing lists