regressions.lists.linux.dev archive mirror
 help / color / mirror / Atom feed
* [REGRESSION] v6.1+ bind() does not fail with EADDRINUSE if dual stack is bound
@ 2023-03-10 16:01 Paul Holzinger
  2023-03-10 21:25 ` Kuniyuki Iwashima
  2023-04-05 13:31 ` Linux regression tracking #adding (Thorsten Leemhuis)
  0 siblings, 2 replies; 4+ messages in thread
From: Paul Holzinger @ 2023-03-10 16:01 UTC (permalink / raw)
  To: stable; +Cc: netdev, regressions, martin.lau, kuba

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.


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


^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2023-04-05 13:32 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-03-10 16:01 [REGRESSION] v6.1+ bind() does not fail with EADDRINUSE if dual stack is bound Paul Holzinger
2023-03-10 21:25 ` Kuniyuki Iwashima
2023-03-10 22:37   ` Kuniyuki Iwashima
2023-04-05 13:31 ` Linux regression tracking #adding (Thorsten Leemhuis)

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).