Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 3 Jun 2021 13:29:05 GMT
From:      Mark Johnston <markj@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org
Subject:   git: fcf938e09396 - stable/13 - tcp, udp: Permit binding with AF_UNSPEC if the address is INADDR_ANY
Message-ID:  <202106031329.153DT5Qk017262@gitrepo.freebsd.org>

next in thread | raw e-mail | index | archive | help
The branch stable/13 has been updated by markj:

URL: https://cgit.FreeBSD.org/src/commit/?id=fcf938e093963bd0a0d92e55c964cfb0b2ce3459

commit fcf938e093963bd0a0d92e55c964cfb0b2ce3459
Author:     Mark Johnston <markj@FreeBSD.org>
AuthorDate: 2021-05-31 22:53:34 +0000
Commit:     Mark Johnston <markj@FreeBSD.org>
CommitDate: 2021-06-03 13:28:53 +0000

    tcp, udp: Permit binding with AF_UNSPEC if the address is INADDR_ANY
    
    Prior to commit f161d294b we only checked the sockaddr length, but now
    we verify the address family as well.  This breaks at least ttcp.  Relax
    the check to avoid breaking compatibility too much: permit AF_UNSPEC if
    the address is INADDR_ANY.
    
    Fixes:          f161d294b
    Reported by:    Bakul Shah <bakul@iitbombay.org>
    Reviewed by:    tuexen
    Sponsored by:   The FreeBSD Foundation
    
    (cherry picked from commit f96603b56f0f74fa52d8f1ef0be869fca7305b99)
---
 sys/netinet/tcp_usrreq.c | 11 +++++++++--
 sys/netinet/udp_usrreq.c | 13 +++++++++++--
 2 files changed, 20 insertions(+), 4 deletions(-)

diff --git a/sys/netinet/tcp_usrreq.c b/sys/netinet/tcp_usrreq.c
index 7132349dbba7..48c3be3ec42c 100644
--- a/sys/netinet/tcp_usrreq.c
+++ b/sys/netinet/tcp_usrreq.c
@@ -321,8 +321,15 @@ tcp_usr_bind(struct socket *so, struct sockaddr *nam, struct thread *td)
 	struct sockaddr_in *sinp;
 
 	sinp = (struct sockaddr_in *)nam;
-	if (nam->sa_family != AF_INET)
-		return (EAFNOSUPPORT);
+	if (nam->sa_family != AF_INET) {
+		/*
+		 * Preserve compatibility with old programs.
+		 */
+		if (nam->sa_family != AF_UNSPEC ||
+		    sinp->sin_addr.s_addr != INADDR_ANY)
+			return (EAFNOSUPPORT);
+		nam->sa_family = AF_INET;
+	}
 	if (nam->sa_len != sizeof(*sinp))
 		return (EINVAL);
 
diff --git a/sys/netinet/udp_usrreq.c b/sys/netinet/udp_usrreq.c
index 62a07701df6c..5c9dbd36a1d6 100644
--- a/sys/netinet/udp_usrreq.c
+++ b/sys/netinet/udp_usrreq.c
@@ -1622,14 +1622,23 @@ udp_bind(struct socket *so, struct sockaddr *nam, struct thread *td)
 {
 	struct inpcb *inp;
 	struct inpcbinfo *pcbinfo;
+	struct sockaddr_in *sinp;
 	int error;
 
 	pcbinfo = udp_get_inpcbinfo(so->so_proto->pr_protocol);
 	inp = sotoinpcb(so);
 	KASSERT(inp != NULL, ("udp_bind: inp == NULL"));
 
-	if (nam->sa_family != AF_INET)
-		return (EAFNOSUPPORT);
+	sinp = (struct sockaddr_in *)nam;
+	if (nam->sa_family != AF_INET) {
+		/*
+		 * Preserve compatibility with old programs.
+		 */
+		if (nam->sa_family != AF_UNSPEC ||
+		    sinp->sin_addr.s_addr != INADDR_ANY)
+			return (EAFNOSUPPORT);
+		nam->sa_family = AF_INET;
+	}
 	if (nam->sa_len != sizeof(struct sockaddr_in))
 		return (EINVAL);
 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202106031329.153DT5Qk017262>