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 for Android: free password hash cracker in your pocket
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20200221203522.25716-1-kuniyu@amazon.co.jp>
Date:   Sat, 22 Feb 2020 05:35:22 +0900
From:   Kuniyuki Iwashima <kuniyu@...zon.co.jp>
To:     <edumazet@...gle.com>
CC:     <davem@...emloft.net>, <kuni1840@...il.com>, <kuniyu@...zon.co.jp>,
        <kuznet@....inr.ac.ru>, <netdev@...r.kernel.org>,
        <osa-contribution-log@...zon.com>, <yoshfuji@...ux-ipv6.org>
Subject: Re: [PATCH net-next 0/3] ImpArove bind(addr, 0) behaviour.

From:   Eric Dumazet <edumazet@...gle.com>
Date:   Thu, 20 Feb 2020 11:58:00 -0800
> On Thu, Feb 20, 2020 at 7:20 AM Kuniyuki Iwashima <kuniyu@...zon.co.jp> wrote:
> >
> > 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.
> >
> > Kuniyuki Iwashima (3):
> >   tcp: Remove unnecessary conditions in inet_csk_bind_conflict().
> >   tcp: bind(addr, 0) remove the SO_REUSEADDR restriction when ephemeral
> >     ports are exhausted.
> >   tcp: Prevent port hijacking when ports are exhausted
> >
> >  net/ipv4/inet_connection_sock.c | 36 ++++++++++++++++++++++-----------
> >  1 file changed, 24 insertions(+), 12 deletions(-)
> 
> I am travelling at the moment, so I can not really look at these
> patches with enough time.
> 
> I would appreciate it if you provide tests to demonstrate your patches are safe.
> 
> Thanks.

I wrote a program below and run without patches and with patches.
Without patches, we cannot reuse ports in any pattern. With patches, we can
reuse ports if all of the socket have SO_REUSEADDR enabled and the first
socket is not in TCP_LISTEN.

So, I am sorry that the description of my third patch is wrong.

>     In this case, we should be able to bind sockets to the same port only if
>     the user has the first listening socket on the port

Also, I succeeded to reuse ports if both sockets are in TCP_CLOSE and have
SO_REUSEADDR and SO_REUSEPORT enabled, and I succeeded to call listen for
both sockets. I think only this case is not safe, so let me check the
condition.

Thank you.

=====
#include <arpa/inet.h>
#include <errno.h>
#include <netinet/in.h>
#include <stdio.h>
#include <string.h>
#include <sys/socket.h>


char *str[] = {
	"both",
	"sk1",
	"sk2",
	"none",
};

#define render_opt(x, i) (x[i] && x[i+1] ? str[0] :	\
			  (x[i] ? str[1] :		\
			   (x[i+1]? str[2] : str[3])))

int main(void) {
	struct sockaddr_in local_addr;	
	char addr[] = "10.0.2.15";
	char ip_str[16];
	unsigned int port;
	int fd[2];
	int len = sizeof(local_addr);
	int error = 0;
	int reuseaddr, reuseport;
	int opts[16][4] = { /* SO_REUSEADDR 1,2  SO_REUSEPORT 1,2 */
		{0,0,0,0},
		{0,0,0,1},
		{0,0,1,0},
		{0,0,1,1},

		{0,1,0,0},
		{0,1,0,1},
		{0,1,1,0},
		{0,1,1,1},

		{1,0,0,0},
		{1,0,0,1},
		{1,0,1,0},
		{1,0,1,1},

		{1,1,0,0},
		{1,1,0,1},
		{1,1,1,0},
		{1,1,1,1}
	};
	int listen_opt[4][2] = {
		{0,0},
		{1,0},
		{0,1},
		{1,1}
	};

	printf("SO_REUSEADDR\tSO_REUSEPORT\tLISTEN\tADDR1\t\t\tADDR2\t\t\tRESULT\n");

	for (int i = 0; i < 16; i++) {
		for (int l = 0; l < 4; l++) {
			printf("%s\t\t%s\t\t%s\t",
			       render_opt(opts[i], 0),
			       render_opt(opts[i], 2),
			       render_opt(listen_opt[l], 0));

			for (int j = 0; j < 2; j++) {
				fd[j] = socket(AF_INET, SOCK_STREAM, 0);

				reuseaddr = opts[i][j];
				reuseport = opts[i][j + 2];
				setsockopt(fd[j], SOL_SOCKET, SO_REUSEADDR, &reuseaddr, sizeof(int));
				setsockopt(fd[j], SOL_SOCKET, SO_REUSEPORT, &reuseport, sizeof(int));

				memset(&local_addr, 0, sizeof(local_addr));
				local_addr.sin_family = AF_INET;
				local_addr.sin_addr.s_addr = inet_addr(addr);
				local_addr.sin_port = 0;

				error = bind(fd[j], (struct sockaddr *)&local_addr, len);

				memset(&local_addr, 0, sizeof(local_addr));
				getsockname(fd[j], (struct sockaddr *)&local_addr, &len);
				inet_ntop(AF_INET, &local_addr.sin_addr, ip_str, sizeof(ip_str));
				port = ntohs(local_addr.sin_port);

				printf("%s:%u\t\t", ip_str, port);

				if (error < 0)
					goto error;

				if (listen_opt[l][j] == 1) {
					error = listen(fd[j], 5);
					if (error < 0)
						goto error;
				}
			}

			printf("o\n");
			goto close;
		error:
			printf("x\t%d: %s\n", errno, strerror(errno));
		close:
			close(fd[0]);
			close(fd[1]);
		}
	}

	return 0;
}
=====


===Without patches===
# sysctl -w net.ipv4.ip_local_port_range="32768 32768"
[    9.830967] ip_local_port_range: prefer different parity for start/end values.
net.ipv4.ip_local_port_range = 32768 32768
# ./reuse
SO_REUSEADDR	SO_REUSEPORT	LISTEN	ADDR1			ADDR2			RESULT
none		none		none	10.0.2.15:32768		0.0.0.0:0		x	98: Address already in use
none		none		sk1	10.0.2.15:32768		0.0.0.0:0		x	98: Address already in use
none		none		sk2	10.0.2.15:32768		0.0.0.0:0		x	98: Address already in use
none		none		both	10.0.2.15:32768		0.0.0.0:0		x	98: Address already in use
none		sk2		none	10.0.2.15:32768		0.0.0.0:0		x	98: Address already in use
none		sk2		sk1	10.0.2.15:32768		0.0.0.0:0		x	98: Address already in use
none		sk2		sk2	10.0.2.15:32768		0.0.0.0:0		x	98: Address already in use
none		sk2		both	10.0.2.15:32768		0.0.0.0:0		x	98: Address already in use
none		sk1		none	10.0.2.15:32768		0.0.0.0:0		x	98: Address already in use
none		sk1		sk1	10.0.2.15:32768		0.0.0.0:0		x	98: Address already in use
none		sk1		sk2	10.0.2.15:32768		0.0.0.0:0		x	98: Address already in use
none		sk1		both	10.0.2.15:32768		0.0.0.0:0		x	98: Address already in use
none		both		none	10.0.2.15:32768		0.0.0.0:0		x	98: Address already in use
none		both		sk1	10.0.2.15:32768		0.0.0.0:0		x	98: Address already in use
none		both		sk2	10.0.2.15:32768		0.0.0.0:0		x	98: Address already in use
none		both		both	10.0.2.15:32768		0.0.0.0:0		x	98: Address already in use
sk2		none		none	10.0.2.15:32768		0.0.0.0:0		x	98: Address already in use
sk2		none		sk1	10.0.2.15:32768		0.0.0.0:0		x	98: Address already in use
sk2		none		sk2	10.0.2.15:32768		0.0.0.0:0		x	98: Address already in use
sk2		none		both	10.0.2.15:32768		0.0.0.0:0		x	98: Address already in use
sk2		sk2		none	10.0.2.15:32768		0.0.0.0:0		x	98: Address already in use
sk2		sk2		sk1	10.0.2.15:32768		0.0.0.0:0		x	98: Address already in use
sk2		sk2		sk2	10.0.2.15:32768		0.0.0.0:0		x	98: Address already in use
sk2		sk2		both	10.0.2.15:32768		0.0.0.0:0		x	98: Address already in use
sk2		sk1		none	10.0.2.15:32768		0.0.0.0:0		x	98: Address already in use
sk2		sk1		sk1	10.0.2.15:32768		0.0.0.0:0		x	98: Address already in use
sk2		sk1		sk2	10.0.2.15:32768		0.0.0.0:0		x	98: Address already in use
sk2		sk1		both	10.0.2.15:32768		0.0.0.0:0		x	98: Address already in use
sk2		both		none	10.0.2.15:32768		0.0.0.0:0		x	98: Address already in use
sk2		both		sk1	10.0.2.15:32768		0.0.0.0:0		x	98: Address already in use
sk2		both		sk2	10.0.2.15:32768		0.0.0.0:0		x	98: Address already in use
sk2		both		both	10.0.2.15:32768		0.0.0.0:0		x	98: Address already in use
sk1		none		none	10.0.2.15:32768		0.0.0.0:0		x	98: Address already in use
sk1		none		sk1	10.0.2.15:32768		0.0.0.0:0		x	98: Address already in use
sk1		none		sk2	10.0.2.15:32768		0.0.0.0:0		x	98: Address already in use
sk1		none		both	10.0.2.15:32768		0.0.0.0:0		x	98: Address already in use
sk1		sk2		none	10.0.2.15:32768		0.0.0.0:0		x	98: Address already in use
sk1		sk2		sk1	10.0.2.15:32768		0.0.0.0:0		x	98: Address already in use
sk1		sk2		sk2	10.0.2.15:32768		0.0.0.0:0		x	98: Address already in use
sk1		sk2		both	10.0.2.15:32768		0.0.0.0:0		x	98: Address already in use
sk1		sk1		none	10.0.2.15:32768		0.0.0.0:0		x	98: Address already in use
sk1		sk1		sk1	10.0.2.15:32768		0.0.0.0:0		x	98: Address already in use
sk1		sk1		sk2	10.0.2.15:32768		0.0.0.0:0		x	98: Address already in use
sk1		sk1		both	10.0.2.15:32768		0.0.0.0:0		x	98: Address already in use
sk1		both		none	10.0.2.15:32768		0.0.0.0:0		x	98: Address already in use
sk1		both		sk1	10.0.2.15:32768		0.0.0.0:0		x	98: Address already in use
sk1		both		sk2	10.0.2.15:32768		0.0.0.0:0		x	98: Address already in use
sk1		both		both	10.0.2.15:32768		0.0.0.0:0		x	98: Address already in use
both		none		none	10.0.2.15:32768		0.0.0.0:0		x	98: Address already in use
both		none		sk1	10.0.2.15:32768		0.0.0.0:0		x	98: Address already in use
both		none		sk2	10.0.2.15:32768		0.0.0.0:0		x	98: Address already in use
both		none		both	10.0.2.15:32768		0.0.0.0:0		x	98: Address already in use
both		sk2		none	10.0.2.15:32768		0.0.0.0:0		x	98: Address already in use
both		sk2		sk1	10.0.2.15:32768		0.0.0.0:0		x	98: Address already in use
both		sk2		sk2	10.0.2.15:32768		0.0.0.0:0		x	98: Address already in use
both		sk2		both	10.0.2.15:32768		0.0.0.0:0		x	98: Address already in use
both		sk1		none	10.0.2.15:32768		0.0.0.0:0		x	98: Address already in use
both		sk1		sk1	10.0.2.15:32768		0.0.0.0:0		x	98: Address already in use
both		sk1		sk2	10.0.2.15:32768		0.0.0.0:0		x	98: Address already in use
both		sk1		both	10.0.2.15:32768		0.0.0.0:0		x	98: Address already in use
both		both		none	10.0.2.15:32768		0.0.0.0:0		x	98: Address already in use
both		both		sk1	10.0.2.15:32768		0.0.0.0:0		x	98: Address already in use
both		both		sk2	10.0.2.15:32768		0.0.0.0:0		x	98: Address already in use
both		both		both	10.0.2.15:32768		0.0.0.0:0		x	98: Address already in use
=====================


===With patches===
# sysctl -w net.ipv4.ip_local_port_range="32768 32768"
[   21.732038] ip_local_port_range: prefer different parity for start/end values.
net.ipv4.ip_local_port_range = 32768 32768
# ./reuse
SO_REUSEADDR	SO_REUSEPORT	LISTEN	ADDR1			ADDR2			RESULT
none		none		none	10.0.2.15:32768		0.0.0.0:0		x	98: Address already in use
none		none		sk1	10.0.2.15:32768		0.0.0.0:0		x	98: Address already in use
none		none		sk2	10.0.2.15:32768		0.0.0.0:0		x	98: Address already in use
none		none		both	10.0.2.15:32768		0.0.0.0:0		x	98: Address already in use
none		sk2		none	10.0.2.15:32768		0.0.0.0:0		x	98: Address already in use
none		sk2		sk1	10.0.2.15:32768		0.0.0.0:0		x	98: Address already in use
none		sk2		sk2	10.0.2.15:32768		0.0.0.0:0		x	98: Address already in use
none		sk2		both	10.0.2.15:32768		0.0.0.0:0		x	98: Address already in use
none		sk1		none	10.0.2.15:32768		0.0.0.0:0		x	98: Address already in use
none		sk1		sk1	10.0.2.15:32768		0.0.0.0:0		x	98: Address already in use
none		sk1		sk2	10.0.2.15:32768		0.0.0.0:0		x	98: Address already in use
none		sk1		both	10.0.2.15:32768		0.0.0.0:0		x	98: Address already in use
none		both		none	10.0.2.15:32768		0.0.0.0:0		x	98: Address already in use
none		both		sk1	10.0.2.15:32768		0.0.0.0:0		x	98: Address already in use
none		both		sk2	10.0.2.15:32768		0.0.0.0:0		x	98: Address already in use
none		both		both	10.0.2.15:32768		0.0.0.0:0		x	98: Address already in use
sk2		none		none	10.0.2.15:32768		0.0.0.0:0		x	98: Address already in use
sk2		none		sk1	10.0.2.15:32768		0.0.0.0:0		x	98: Address already in use
sk2		none		sk2	10.0.2.15:32768		0.0.0.0:0		x	98: Address already in use
sk2		none		both	10.0.2.15:32768		0.0.0.0:0		x	98: Address already in use
sk2		sk2		none	10.0.2.15:32768		0.0.0.0:0		x	98: Address already in use
sk2		sk2		sk1	10.0.2.15:32768		0.0.0.0:0		x	98: Address already in use
sk2		sk2		sk2	10.0.2.15:32768		0.0.0.0:0		x	98: Address already in use
sk2		sk2		both	10.0.2.15:32768		0.0.0.0:0		x	98: Address already in use
sk2		sk1		none	10.0.2.15:32768		0.0.0.0:0		x	98: Address already in use
sk2		sk1		sk1	10.0.2.15:32768		0.0.0.0:0		x	98: Address already in use
sk2		sk1		sk2	10.0.2.15:32768		0.0.0.0:0		x	98: Address already in use
sk2		sk1		both	10.0.2.15:32768		0.0.0.0:0		x	98: Address already in use
sk2		both		none	10.0.2.15:32768		0.0.0.0:0		x	98: Address already in use
sk2		both		sk1	10.0.2.15:32768		0.0.0.0:0		x	98: Address already in use
sk2		both		sk2	10.0.2.15:32768		0.0.0.0:0		x	98: Address already in use
sk2		both		both	10.0.2.15:32768		0.0.0.0:0		x	98: Address already in use
sk1		none		none	10.0.2.15:32768		0.0.0.0:0		x	98: Address already in use
sk1		none		sk1	10.0.2.15:32768		0.0.0.0:0		x	98: Address already in use
sk1		none		sk2	10.0.2.15:32768		0.0.0.0:0		x	98: Address already in use
sk1		none		both	10.0.2.15:32768		0.0.0.0:0		x	98: Address already in use
sk1		sk2		none	10.0.2.15:32768		0.0.0.0:0		x	98: Address already in use
sk1		sk2		sk1	10.0.2.15:32768		0.0.0.0:0		x	98: Address already in use
sk1		sk2		sk2	10.0.2.15:32768		0.0.0.0:0		x	98: Address already in use
sk1		sk2		both	10.0.2.15:32768		0.0.0.0:0		x	98: Address already in use
sk1		sk1		none	10.0.2.15:32768		0.0.0.0:0		x	98: Address already in use
sk1		sk1		sk1	10.0.2.15:32768		0.0.0.0:0		x	98: Address already in use
sk1		sk1		sk2	10.0.2.15:32768		0.0.0.0:0		x	98: Address already in use
sk1		sk1		both	10.0.2.15:32768		0.0.0.0:0		x	98: Address already in use
sk1		both		none	10.0.2.15:32768		0.0.0.0:0		x	98: Address already in use
sk1		both		sk1	10.0.2.15:32768		0.0.0.0:0		x	98: Address already in use
sk1		both		sk2	10.0.2.15:32768		0.0.0.0:0		x	98: Address already in use
sk1		both		both	10.0.2.15:32768		0.0.0.0:0		x	98: Address already in use
both		none		none	10.0.2.15:32768		10.0.2.15:32768		o
both		none		sk1	10.0.2.15:32768		0.0.0.0:0		x	98: Address already in use
both		none		sk2	10.0.2.15:32768		10.0.2.15:32768		o
both		none		both	10.0.2.15:32768		0.0.0.0:0		x	98: Address already in use
both		sk2		none	10.0.2.15:32768		10.0.2.15:32768		o
both		sk2		sk1	10.0.2.15:32768		0.0.0.0:0		x	98: Address already in use
both		sk2		sk2	10.0.2.15:32768		10.0.2.15:32768		o
both		sk2		both	10.0.2.15:32768		0.0.0.0:0		x	98: Address already in use
both		sk1		none	10.0.2.15:32768		10.0.2.15:32768		o
both		sk1		sk1	10.0.2.15:32768		0.0.0.0:0		x	98: Address already in use
both		sk1		sk2	10.0.2.15:32768		10.0.2.15:32768		o
both		sk1		both	10.0.2.15:32768		0.0.0.0:0		x	98: Address already in use
both		both		none	10.0.2.15:32768		10.0.2.15:32768		o
both		both		sk1	10.0.2.15:32768		0.0.0.0:0		x	98: Address already in use
both		both		sk2	10.0.2.15:32768		10.0.2.15:32768		o
both		both		both	10.0.2.15:32768		0.0.0.0:0		x	98: Address already in use
==================

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ