svn commit: r335501 - head/sys/netinet

Matt Macy mmacy at FreeBSD.org
Thu Jun 21 20:18:24 UTC 2018


Author: mmacy
Date: Thu Jun 21 20:18:23 2018
New Revision: 335501
URL: https://svnweb.freebsd.org/changeset/base/335501

Log:
  raw_ip: validate inp in both loops
  
  Continuation of r335497. Also move the lock acquisition up to
  validate before referencing inp_cred.
  
  Reported by:	pho

Modified:
  head/sys/netinet/raw_ip.c

Modified: head/sys/netinet/raw_ip.c
==============================================================================
--- head/sys/netinet/raw_ip.c	Thu Jun 21 18:40:15 2018	(r335500)
+++ head/sys/netinet/raw_ip.c	Thu Jun 21 20:18:23 2018	(r335501)
@@ -312,29 +312,31 @@ rip_input(struct mbuf **mp, int *offp, int proto)
 			continue;
 		if (inp->inp_faddr.s_addr != ip->ip_src.s_addr)
 			continue;
-		if (jailed_without_vnet(inp->inp_cred)) {
-			/*
-			 * XXX: If faddr was bound to multicast group,
-			 * jailed raw socket will drop datagram.
-			 */
-			if (prison_check_ip4(inp->inp_cred, &ip->ip_dst) != 0)
-				continue;
-		}
 		if (last != NULL) {
 			struct mbuf *n;
 
 			n = m_copym(m, 0, M_COPYALL, M_NOWAIT);
 			if (n != NULL)
-		    	    (void) rip_append(last, ip, n, &ripsrc);
+			    (void) rip_append(last, ip, n, &ripsrc);
 			/* XXX count dropped packet */
 			INP_RUNLOCK(last);
+			last = NULL;
 		}
 		INP_RLOCK(inp);
-		last = inp;
-		if (__predict_false(inp->inp_flags2 & INP_FREED)) {
-			last = NULL;
-			INP_RUNLOCK(inp);
+		if (__predict_false(inp->inp_flags2 & INP_FREED))
+			goto skip_1;
+		if (jailed_without_vnet(inp->inp_cred)) {
+			/*
+			 * XXX: If faddr was bound to multicast group,
+			 * jailed raw socket will drop datagram.
+			 */
+			if (prison_check_ip4(inp->inp_cred, &ip->ip_dst) != 0)
+				goto skip_1;
 		}
+		last = inp;
+		continue;
+	skip_1:
+		INP_RUNLOCK(inp);
 	}
 	CK_LIST_FOREACH(inp, &V_ripcbinfo.ipi_hashbase[0], inp_hash) {
 		if (inp->inp_ip_p && inp->inp_ip_p != proto)
@@ -350,6 +352,19 @@ rip_input(struct mbuf **mp, int *offp, int proto)
 		if (!in_nullhost(inp->inp_faddr) &&
 		    !in_hosteq(inp->inp_faddr, ip->ip_src))
 			continue;
+		if (last != NULL) {
+			struct mbuf *n;
+
+			n = m_copym(m, 0, M_COPYALL, M_NOWAIT);
+			if (n != NULL)
+				(void) rip_append(last, ip, n, &ripsrc);
+			/* XXX count dropped packet */
+			INP_RUNLOCK(last);
+			last = NULL;
+		}
+		INP_RLOCK(inp);
+		if (__predict_false(inp->inp_flags2 & INP_FREED))
+			goto skip_2;
 		if (jailed_without_vnet(inp->inp_cred)) {
 			/*
 			 * Allow raw socket in jail to receive multicast;
@@ -358,7 +373,7 @@ rip_input(struct mbuf **mp, int *offp, int proto)
 			 */
 			if (!IN_MULTICAST(ntohl(ip->ip_dst.s_addr)) &&
 			    prison_check_ip4(inp->inp_cred, &ip->ip_dst) != 0)
-				continue;
+				goto skip_2;
 		}
 		/*
 		 * If this raw socket has multicast state, and we
@@ -399,20 +414,13 @@ rip_input(struct mbuf **mp, int *offp, int proto)
 
 			if (blocked != MCAST_PASS) {
 				IPSTAT_INC(ips_notmember);
-				continue;
+				goto skip_2;
 			}
 		}
-		if (last != NULL) {
-			struct mbuf *n;
-
-			n = m_copym(m, 0, M_COPYALL, M_NOWAIT);
-			if (n != NULL)
-				(void) rip_append(last, ip, n, &ripsrc);
-			/* XXX count dropped packet */
-			INP_RUNLOCK(last);
-		}
-		INP_RLOCK(inp);
 		last = inp;
+		continue;
+	skip_2:
+		INP_RUNLOCK(inp);
 	}
 	INP_INFO_RUNLOCK(&V_ripcbinfo);
 	if (last != NULL) {


More information about the svn-src-all mailing list