svn commit: r331379 - in head/sys: netinet netinet6

Sean Bruno sbruno at FreeBSD.org
Thu Mar 22 22:29:33 UTC 2018


Author: sbruno
Date: Thu Mar 22 22:29:32 2018
New Revision: 331379
URL: https://svnweb.freebsd.org/changeset/base/331379

Log:
  Simple locking fixes in ip_ctloutput, ip6_ctloutput, rip_ctloutput.
  
  Submitted by:	Jason Eggleston <jason at eggnet.com>
  Sponsored by:	Limelight Networks
  Differential Revision:	https://reviews.freebsd.org/D14624

Modified:
  head/sys/netinet/ip_output.c
  head/sys/netinet/raw_ip.c
  head/sys/netinet6/ip6_output.c

Modified: head/sys/netinet/ip_output.c
==============================================================================
--- head/sys/netinet/ip_output.c	Thu Mar 22 22:13:46 2018	(r331378)
+++ head/sys/netinet/ip_output.c	Thu Mar 22 22:29:32 2018	(r331379)
@@ -1314,12 +1314,14 @@ ip_ctloutput(struct socket *so, struct sockopt *sopt)
 				break;
 
 			case IP_PORTRANGE:
+				INP_RLOCK(inp);
 				if (inp->inp_flags & INP_HIGHPORT)
 					optval = IP_PORTRANGE_HIGH;
 				else if (inp->inp_flags & INP_LOWPORT)
 					optval = IP_PORTRANGE_LOW;
 				else
 					optval = 0;
+				INP_RUNLOCK(inp);
 				break;
 
 			case IP_ONESBCAST:
@@ -1345,9 +1347,11 @@ ip_ctloutput(struct socket *so, struct sockopt *sopt)
 				break;
 #ifdef	RSS
 			case IP_RSSBUCKETID:
+				INP_RLOCK(inp);
 				retval = rss_hash2bucket(inp->inp_flowid,
 				    inp->inp_flowtype,
 				    &rss_bucket);
+				INP_RUNLOCK(inp);
 				if (retval == 0)
 					optval = rss_bucket;
 				else

Modified: head/sys/netinet/raw_ip.c
==============================================================================
--- head/sys/netinet/raw_ip.c	Thu Mar 22 22:13:46 2018	(r331378)
+++ head/sys/netinet/raw_ip.c	Thu Mar 22 22:29:32 2018	(r331379)
@@ -639,10 +639,12 @@ rip_ctloutput(struct socket *so, struct sockopt *sopt)
 					    sizeof optval);
 			if (error)
 				break;
+			INP_WLOCK(inp);
 			if (optval)
 				inp->inp_flags |= INP_HDRINCL;
 			else
 				inp->inp_flags &= ~INP_HDRINCL;
+			INP_WUNLOCK(inp);
 			break;
 
 		case IP_FW3:	/* generic ipfw v.3 functions */

Modified: head/sys/netinet6/ip6_output.c
==============================================================================
--- head/sys/netinet6/ip6_output.c	Thu Mar 22 22:13:46 2018	(r331378)
+++ head/sys/netinet6/ip6_output.c	Thu Mar 22 22:29:32 2018	(r331379)
@@ -1498,8 +1498,10 @@ ip6_ctloutput(struct socket *so, struct sockopt *sopt)
 				error = soopt_mcopyin(sopt, m); /* XXX */
 				if (error != 0)
 					break;
+				INP_WLOCK(in6p);
 				error = ip6_pcbopts(&in6p->in6p_outputopts,
 						    m, so, sopt);
+				INP_WUNLOCK(in6p);
 				m_freem(m); /* XXX */
 				break;
 			}
@@ -1635,11 +1637,13 @@ do {									\
 						error = EINVAL;
 						break;
 					}
+					INP_WLOCK(in6p);
 					optp = &in6p->in6p_outputopts;
 					error = ip6_pcbopt(IPV6_HOPLIMIT,
 					    (u_char *)&optval, sizeof(optval),
 					    optp, (td != NULL) ? td->td_ucred :
 					    NULL, uproto);
+					INP_WUNLOCK(in6p);
 					break;
 				}
 
@@ -1690,8 +1694,10 @@ do {									\
 					 * available only prior to bind(2).
 					 * see ipng mailing list, Jun 22 2001.
 					 */
+					INP_WLOCK(in6p);
 					if (in6p->inp_lport ||
 					    !IN6_IS_ADDR_UNSPECIFIED(&in6p->in6p_laddr)) {
+						INP_WUNLOCK(in6p);
 						error = EINVAL;
 						break;
 					}
@@ -1700,6 +1706,7 @@ do {									\
 						in6p->inp_vflag &= ~INP_IPV4;
 					else
 						in6p->inp_vflag |= INP_IPV4;
+					INP_WUNLOCK(in6p);
 					break;
 				case IPV6_RECVTCLASS:
 					/* cannot mix with RFC2292 XXX */
@@ -1749,11 +1756,13 @@ do {									\
 					break;
 				{
 					struct ip6_pktopts **optp;
+					INP_WLOCK(in6p);
 					optp = &in6p->in6p_outputopts;
 					error = ip6_pcbopt(optname,
 					    (u_char *)&optval, sizeof(optval),
 					    optp, (td != NULL) ? td->td_ucred :
 					    NULL, uproto);
+					INP_WUNLOCK(in6p);
 					break;
 				}
 
@@ -1818,12 +1827,6 @@ do {									\
 				int optlen;
 				struct ip6_pktopts **optp;
 
-				/* cannot mix with RFC2292 */
-				if (OPTBIT(IN6P_RFC2292)) {
-					error = EINVAL;
-					break;
-				}
-
 				/*
 				 * We only ensure valsize is not too large
 				 * here.  Further validation will be done
@@ -1833,12 +1836,21 @@ do {									\
 				    sizeof(optbuf_storage), 0);
 				if (error)
 					break;
+
+				INP_WLOCK(in6p);
+				/* cannot mix with RFC2292 */
+				if (OPTBIT(IN6P_RFC2292)) {
+					INP_WUNLOCK(in6p);
+					error = EINVAL;
+					break;
+				}
 				optlen = sopt->sopt_valsize;
 				optbuf = optbuf_storage;
 				optp = &in6p->in6p_outputopts;
 				error = ip6_pcbopt(optname, optbuf, optlen,
 				    optp, (td != NULL) ? td->td_ucred : NULL,
 				    uproto);
+				INP_WUNLOCK(in6p);
 				break;
 			}
 #undef OPTSET
@@ -2023,10 +2035,12 @@ do {									\
 					break;
 #ifdef	RSS
 				case IPV6_RSSBUCKETID:
+					INP_RLOCK(in6p);
 					retval =
 					    rss_hash2bucket(in6p->inp_flowid,
 					    in6p->inp_flowtype,
 					    &rss_bucket);
+					INP_RUNLOCK(in6p);
 					if (retval == 0)
 						optval = rss_bucket;
 					else
@@ -2230,6 +2244,8 @@ ip6_pcbopts(struct ip6_pktopts **pktopt, struct mbuf *
 	int error = 0;
 	struct thread *td = sopt->sopt_td;
 
+	INP_WLOCK_ASSERT(sotoinpcb(so));
+
 	/* turn off any old options. */
 	if (opt) {
 #ifdef DIAGNOSTIC
@@ -3073,6 +3089,8 @@ int
 ip6_optlen(struct inpcb *in6p)
 {
 	int len;
+
+	INP_WLOCK_ASSERT(in6p);
 
 	if (!in6p->in6p_outputopts)
 		return 0;


More information about the svn-src-all mailing list