From: Paul Holzinger <pholzing@xxxxxxxxxx> Date: Fri, 10 Mar 2023 17:01:31 +0100 > Hi all, > > there seems to be a regression which allows you to bind the same port > twice when the first bind call bound to all ip addresses (i. e. dual stack). > > A second bind call for the same port will succeed if you try to bind to > a specific ipv4 (e. g. 127.0.0.1), binding to 0.0.0.0 or an ipv6 address > fails correctly with EADDRINUSE. > > I included a small c program below to show the issue. Normally the > second bind call should fail, this was the case before v6.1. > > > I bisected the regression to commit 5456262d2baa ("net: Fix incorrect > address comparison when searching for a bind2 bucket"). > > I also checked that the issue is still present in v6.3-rc1. Thanks for the detailed report. It seems we should take care of the special case in inet_bind2_bucket_match_addr_any(). I'll fix it. Thanks, Kuniyuki > > > Original report: https://github.com/containers/podman/issues/17719 > > #regzbot introduced: 5456262d2baa > > > ``` > > #include <sys/socket.h> > #include <sys/un.h> > #include <stdlib.h> > #include <stdio.h> > #include <netinet/in.h> > #include <unistd.h> > > int main(int argc, char *argv[]) > { > int ret, sock1, sock2; > struct sockaddr_in6 addr; > struct sockaddr_in addr2; > > sock1 = socket(AF_INET6, SOCK_STREAM, 0); > if (sock1 == -1) > { > perror("socket1"); > exit(1); > } > sock2 = socket(AF_INET, SOCK_STREAM, 0); > if (sock2 == -1) > { > perror("socket2"); > exit(1); > } > > memset(&addr, 0, sizeof(addr)); > addr.sin6_family = AF_INET6; > addr.sin6_addr = in6addr_any; > addr.sin6_port = htons(8080); > > memset(&addr2, 0, sizeof(addr2)); > addr2.sin_family = AF_INET; > addr2.sin_addr.s_addr = htonl(INADDR_LOOPBACK); > addr2.sin_port = htons(8080); > > ret = bind(sock1, (struct sockaddr *)&addr, sizeof(addr)); > if (ret == -1) > { > perror("bind1"); > exit(1); > } > printf("bind1 ret: %d\n", ret); > > if ((listen(sock1, 5)) != 0) > { > perror("listen1"); > exit(1); > } > > ret = bind(sock2, (struct sockaddr *)&addr2, sizeof(addr2)); > if (ret == -1) > { > perror("bind2"); > exit(1); > } > printf("bind2 ret: %d\n", ret); > > if ((listen(sock2, 5)) != 0) > { > perror("listen2"); > exit(1); > } > > // uncomment pause() to see with ss -tlpn the bound ports > // pause(); > > return 0; > } > > ``` > > > Best regards, > > Paul