cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

reuseaddr_conflict.c (2688B)


      1/*
      2 * Test for the regression introduced by
      3 *
      4 * b9470c27607b ("inet: kill smallest_size and smallest_port")
      5 *
      6 * If we open an ipv4 socket on a port with reuseaddr we shouldn't reset the tb
      7 * when we open the ipv6 conterpart, which is what was happening previously.
      8 */
      9#include <errno.h>
     10#include <error.h>
     11#include <arpa/inet.h>
     12#include <netinet/in.h>
     13#include <stdbool.h>
     14#include <stdio.h>
     15#include <sys/socket.h>
     16#include <sys/types.h>
     17#include <unistd.h>
     18
     19#define PORT 9999
     20
     21int open_port(int ipv6, int any)
     22{
     23	int fd = -1;
     24	int reuseaddr = 1;
     25	int v6only = 1;
     26	int addrlen;
     27	int ret = -1;
     28	struct sockaddr *addr;
     29	int family = ipv6 ? AF_INET6 : AF_INET;
     30
     31	struct sockaddr_in6 addr6 = {
     32		.sin6_family = AF_INET6,
     33		.sin6_port = htons(PORT),
     34		.sin6_addr = in6addr_any
     35	};
     36	struct sockaddr_in addr4 = {
     37		.sin_family = AF_INET,
     38		.sin_port = htons(PORT),
     39		.sin_addr.s_addr = any ? htonl(INADDR_ANY) : inet_addr("127.0.0.1"),
     40	};
     41
     42
     43	if (ipv6) {
     44		addr = (struct sockaddr*)&addr6;
     45		addrlen = sizeof(addr6);
     46	} else {
     47		addr = (struct sockaddr*)&addr4;
     48		addrlen = sizeof(addr4);
     49	}
     50
     51	if ((fd = socket(family, SOCK_STREAM, IPPROTO_TCP)) < 0) {
     52		perror("socket");
     53		goto out;
     54	}
     55
     56	if (ipv6 && setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, (void*)&v6only,
     57			       sizeof(v6only)) < 0) {
     58		perror("setsockopt IPV6_V6ONLY");
     59		goto out;
     60	}
     61
     62	if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &reuseaddr,
     63		       sizeof(reuseaddr)) < 0) {
     64		perror("setsockopt SO_REUSEADDR");
     65		goto out;
     66	}
     67
     68	if (bind(fd, addr, addrlen) < 0) {
     69		perror("bind");
     70		goto out;
     71	}
     72
     73	if (any)
     74		return fd;
     75
     76	if (listen(fd, 1) < 0) {
     77		perror("listen");
     78		goto out;
     79	}
     80	return fd;
     81out:
     82	close(fd);
     83	return ret;
     84}
     85
     86int main(void)
     87{
     88	int listenfd;
     89	int fd1, fd2;
     90
     91	fprintf(stderr, "Opening 127.0.0.1:%d\n", PORT);
     92	listenfd = open_port(0, 0);
     93	if (listenfd < 0)
     94		error(1, errno, "Couldn't open listen socket");
     95	fprintf(stderr, "Opening INADDR_ANY:%d\n", PORT);
     96	fd1 = open_port(0, 1);
     97	if (fd1 >= 0)
     98		error(1, 0, "Was allowed to create an ipv4 reuseport on a already bound non-reuseport socket");
     99	fprintf(stderr, "Opening in6addr_any:%d\n", PORT);
    100	fd1 = open_port(1, 1);
    101	if (fd1 < 0)
    102		error(1, errno, "Couldn't open ipv6 reuseport");
    103	fprintf(stderr, "Opening INADDR_ANY:%d\n", PORT);
    104	fd2 = open_port(0, 1);
    105	if (fd2 >= 0)
    106		error(1, 0, "Was allowed to create an ipv4 reuseport on a already bound non-reuseport socket");
    107	close(fd1);
    108	fprintf(stderr, "Opening INADDR_ANY:%d after closing ipv6 socket\n", PORT);
    109	fd1 = open_port(0, 1);
    110	if (fd1 >= 0)
    111		error(1, 0, "Was allowed to create an ipv4 reuseport on an already bound non-reuseport socket with no ipv6");
    112	fprintf(stderr, "Success");
    113	return 0;
    114}