git: 24af7808fa12 - main - protosw: repair protocol selection logic in socket(2)

From: Gleb Smirnoff <glebius_at_FreeBSD.org>
Date: Wed, 31 Aug 2022 04:25:45 UTC
The branch main has been updated by glebius:

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

commit 24af7808fa1293f34beb6b7de38894326feeb74f
Author:     Gleb Smirnoff <glebius@FreeBSD.org>
AuthorDate: 2022-08-31 04:19:46 +0000
Commit:     Gleb Smirnoff <glebius@FreeBSD.org>
CommitDate: 2022-08-31 04:19:46 +0000

    protosw: repair protocol selection logic in socket(2)
    
    Pointy hat to:  glebius
    Fixes:          61f7427f02a307d28af674a12c45dd546e3898e4
---
 sys/kern/uipc_domain.c | 6 ++++--
 sys/kern/uipc_socket.c | 4 +---
 sys/sys/protosw.h      | 2 +-
 3 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/sys/kern/uipc_domain.c b/sys/kern/uipc_domain.c
index 832afca510fa..f1b2c616c662 100644
--- a/sys/kern/uipc_domain.c
+++ b/sys/kern/uipc_domain.c
@@ -290,7 +290,7 @@ pffinddomain(int family)
 }
 
 struct protosw *
-pffindtype(int family, int type)
+pffindproto(int family, int type, int proto)
 {
 	struct domain *dp;
 	struct protosw *pr;
@@ -300,7 +300,9 @@ pffindtype(int family, int type)
 		return (NULL);
 
 	for (int i = 0; i < dp->dom_nprotosw; i++)
-		if ((pr = dp->dom_protosw[i]) != NULL && pr->pr_type == type)
+		if ((pr = dp->dom_protosw[i]) != NULL && pr->pr_type == type &&
+		    (pr->pr_protocol == 0 || proto == 0 ||
+		     pr->pr_protocol == proto))
 			return (pr);
 
 	return (NULL);
diff --git a/sys/kern/uipc_socket.c b/sys/kern/uipc_socket.c
index a93256cd7f63..360b7b56cee5 100644
--- a/sys/kern/uipc_socket.c
+++ b/sys/kern/uipc_socket.c
@@ -520,7 +520,7 @@ socreate(int dom, struct socket **aso, int type, int proto,
 		    td->td_proc->p_comm);
 	}
 
-	prp = pffindtype(dom, type);
+	prp = pffindproto(dom, type, proto);
 	if (prp == NULL) {
 		/* No support for domain. */
 		if (pffinddomain(dom) == NULL)
@@ -530,8 +530,6 @@ socreate(int dom, struct socket **aso, int type, int proto,
 			return (EPROTOTYPE);
 		return (EPROTONOSUPPORT);
 	}
-	if (prp->pr_protocol != 0 && proto != 0 && prp->pr_protocol != proto)
-		return (EPROTONOSUPPORT);
 
 	MPASS(prp->pr_attach);
 
diff --git a/sys/sys/protosw.h b/sys/sys/protosw.h
index f05aff962420..3b89c6f78caf 100644
--- a/sys/sys/protosw.h
+++ b/sys/sys/protosw.h
@@ -236,7 +236,7 @@ char	*prcorequests[] = {
 
 #ifdef _KERNEL
 struct domain *pffinddomain(int family);
-struct protosw *pffindtype(int family, int type);
+struct protosw *pffindproto(int family, int type, int proto);
 int protosw_register(struct domain *, struct protosw *);
 int protosw_unregister(struct protosw *);