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] [day] [month] [year] [list]
Date:   Mon, 24 Feb 2020 06:06:45 +0900
From:   Kuniyuki Iwashima <kuniyu@...zon.co.jp>
To:     <kuniyu@...zon.co.jp>
CC:     <davem@...emloft.net>, <edumazet@...gle.com>, <kuni1840@...il.com>,
        <kuznet@....inr.ac.ru>, <netdev@...r.kernel.org>,
        <osa-contribution-log@...zon.com>, <yoshfuji@...ux-ipv6.org>
Subject: Re: [PATCH net-next 0/3] Improve bind(addr, 0) behaviour.

From:   Kuniyuki Iwashima <kuniyu@...zon.co.jp>
Date:   Sat, 22 Feb 2020 10:07:49 +0900
> I also tested with two users. I am sorry about having tested in python,
> I will rewrite it in C later.
> 
> Both of user-a and user-b can get the same port, but one of them failed to
> call listen().

I wrote a test in C and the result was the same.
If all of the sockets bound to the same port have SO_REUSEADDR and
SO_REUSEPORT enabled, two users can bind(), but can only one user listen().

If you would think these patches are safe, I'll respin the patches with
the correct conditon of the 3rd patch.

Thanks.

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


int main(void) {
	struct sockaddr_in local_addr;
	uid_t euid[2] = {1001, 1002};
	int fd[2], error, i, port;
	int len = sizeof(local_addr);
	int reuseaddr = 1, reuseport = 1;
	char ip_str[16];

	for (i = 0; i < 2; i++) {
		if (seteuid(euid[i]) != 0)
			goto error;

		fd[i] = socket(AF_INET, SOCK_STREAM, 0);

		setsockopt(fd[i], SOL_SOCKET, SO_REUSEADDR, &reuseaddr, sizeof(int));
		setsockopt(fd[i], SOL_SOCKET, SO_REUSEPORT, &reuseport, sizeof(int));

		local_addr.sin_family = AF_INET;
		local_addr.sin_addr.s_addr = inet_addr("10.0.2.15");
		local_addr.sin_port = 0;

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

		memset(&local_addr, 0, sizeof(local_addr));
		getsockname(fd[i], (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("euid: %d\tbound to %s:%u\n", euid[i], ip_str, port);

		if (error != 0)
			goto error;

		if (seteuid(0) != 0)
			goto error;
	}

	for (i = 0; i < 2; i++) {
		if (seteuid(euid[i]) != 0)
			goto error;

		error = listen(fd[i], 5);

		if (error < 0)
			printf("euid: %d\tlisten failed\n", euid[i]);
		else
			printf("euid: %d\tlisten succeeded\n", euid[i]);

		if (seteuid(0) != 0)
			goto error;		
	}

	return 0;
error:
	printf("error: %d, %s\n", errno, strerror(errno));
	return -1;
}
=====

===result===
# id user-a
uid=1001(user-a) gid=1001(user-a) groups=1001(user-a)
# id user-b
uid=1002(user-b) gid=1002(user-b) groups=1002(user-b)
# sysctl -w net.ipv4.ip_local_port_range="32768 32768"
[   30.060036] ip_local_port_range: prefer different parity for start/end values.
net.ipv4.ip_local_port_range = 32768 32768
# ./seteuid 
euid: 1001	bound to 10.0.2.15:32768
euid: 1002	bound to 10.0.2.15:32768
euid: 1001	listen succeeded
euid: 1002	listen failed
============

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ