Relax address availability check for multicast binds.
authorclaudio <claudio@openbsd.org>
Thu, 14 Apr 2022 14:10:22 +0000 (14:10 +0000)
committerclaudio <claudio@openbsd.org>
Thu, 14 Apr 2022 14:10:22 +0000 (14:10 +0000)
While it makes sense to limit bind(2) of unicast addresses that overlap
each other to be all from the same UID (like 0.0.0.0:53 and 127.0.0.1:53)
it makes little sense for multicast. Multicast is delivered to all sockets
that match so there is no risk of someone stealing traffic from someone
else.  This should hopefully help with mDNS as reported by robert@
OK deraadt@ bluhm@

sys/netinet/in_pcb.c
sys/netinet6/in6_pcb.c

index 4b00dbf..9d4749f 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: in_pcb.c,v 1.264 2022/03/22 18:02:54 bluhm Exp $      */
+/*     $OpenBSD: in_pcb.c,v 1.265 2022/04/14 14:10:22 claudio Exp $    */
 /*     $NetBSD: in_pcb.c,v 1.25 1996/02/13 23:41:53 christos Exp $     */
 
 /*
@@ -404,7 +404,7 @@ in_pcbaddrisavail(struct inpcb *inp, struct sockaddr_in *sin, int wild,
        if (lport) {
                struct inpcb *t;
 
-               if (so->so_euid) {
+               if (so->so_euid && !IN_MULTICAST(sin->sin_addr.s_addr)) {
                        t = in_pcblookup_local(table, &sin->sin_addr, lport,
                            INPLOOKUP_WILDCARD, inp->inp_rtableid);
                        if (t && (so->so_euid != t->inp_socket->so_euid))
index 75fc61e..115c816 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: in6_pcb.c,v 1.116 2022/03/21 09:12:34 bluhm Exp $     */
+/*     $OpenBSD: in6_pcb.c,v 1.117 2022/04/14 14:10:22 claudio Exp $   */
 
 /*
  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -209,16 +209,14 @@ in6_pcbaddrisavail(struct inpcb *inp, struct sockaddr_in6 *sin6, int wild,
        if (lport) {
                struct inpcb *t;
 
-               if (so->so_euid) {
-                       t = in_pcblookup_local(table,
-                           (struct in_addr *)&sin6->sin6_addr, lport,
+               if (so->so_euid && !IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr)) {
+                       t = in_pcblookup_local(table, &sin6->sin6_addr, lport,
                            INPLOOKUP_WILDCARD | INPLOOKUP_IPV6,
                            inp->inp_rtableid);
                        if (t && (so->so_euid != t->inp_socket->so_euid))
                                return (EADDRINUSE);
                }
-               t = in_pcblookup_local(table,
-                   (struct in_addr *)&sin6->sin6_addr, lport,
+               t = in_pcblookup_local(table, &sin6->sin6_addr, lport,
                    wild, inp->inp_rtableid);
                if (t && (reuseport & t->inp_socket->so_options) == 0)
                        return (EADDRINUSE);