From 417b35a97b7669eb0bf417b43e97cccbedbce6f9 Mon Sep 17 00:00:00 2001 From: Mark Johnston Date: Tue, 20 Aug 2024 21:31:57 +0000 Subject: [PATCH] netinet: Add a sysctl to allow disabling connections to INADDR_ANY See the discussion in Bugzilla PR 280705 for context. PR: 280705 MFC after: 1 week Differential Revision: https://reviews.freebsd.org/D46259 --- sys/netinet/in_pcb.c | 8 +++++++- sys/netinet6/in6_pcb.c | 12 +++++++++++- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/sys/netinet/in_pcb.c b/sys/netinet/in_pcb.c index 1a341d421f3..3fc90f1e12c 100644 --- a/sys/netinet/in_pcb.c +++ b/sys/netinet/in_pcb.c @@ -234,6 +234,12 @@ in_pcbhashseed_init(void) VNET_SYSINIT(in_pcbhashseed_init, SI_SUB_PROTO_DOMAIN, SI_ORDER_FIRST, in_pcbhashseed_init, 0); +VNET_DEFINE_STATIC(int, connect_inaddr_wild) = 1; +#define V_connect_inaddr_wild VNET(connect_inaddr_wild) +SYSCTL_INT(_net_inet_ip, OID_AUTO, connect_inaddr_wild, + CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(connect_inaddr_wild), 0, + "Allow connecting to INADDR_ANY or INADDR_BROADCAST for connect(2)"); + static void in_pcbremhash(struct inpcb *); /* @@ -1309,7 +1315,7 @@ in_pcbconnect_setup(struct inpcb *inp, struct sockaddr_in *sin, inp->inp_flowtype = hash_type; } #endif - if (!CK_STAILQ_EMPTY(&V_in_ifaddrhead)) { + if (V_connect_inaddr_wild && !CK_STAILQ_EMPTY(&V_in_ifaddrhead)) { /* * If the destination address is INADDR_ANY, * use the primary local address. diff --git a/sys/netinet6/in6_pcb.c b/sys/netinet6/in6_pcb.c index e6ec0f24c89..098b4e50483 100644 --- a/sys/netinet6/in6_pcb.c +++ b/sys/netinet6/in6_pcb.c @@ -83,6 +83,7 @@ #include #include #include +#include #include #include #include @@ -97,6 +98,7 @@ #include #include #include +#include #include #include @@ -112,6 +114,14 @@ #include #include +SYSCTL_DECL(_net_inet6); +SYSCTL_DECL(_net_inet6_ip6); +VNET_DEFINE_STATIC(int, connect_in6addr_wild) = 1; +#define V_connect_in6addr_wild VNET(connect_in6addr_wild) +SYSCTL_INT(_net_inet6_ip6, OID_AUTO, connect_in6addr_wild, + CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(connect_in6addr_wild), 0, + "Allow connecting to the unspecified address for connect(2)"); + int in6_pcbsetport(struct in6_addr *laddr, struct inpcb *inp, struct ucred *cred) { @@ -351,7 +361,7 @@ in6_pcbladdr(struct inpcb *inp, struct sockaddr_in6 *sin6, if ((error = sa6_embedscope(sin6, V_ip6_use_defzone)) != 0) return(error); - if (!CK_STAILQ_EMPTY(&V_in6_ifaddrhead)) { + if (V_connect_in6addr_wild && !CK_STAILQ_EMPTY(&V_in6_ifaddrhead)) { /* * If the destination address is UNSPECIFIED addr, * use the loopback addr, e.g ::1.