Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 3 Jul 2018 23:30:53 +0000 (UTC)
From:      Matt Macy <mmacy@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r335919 - head/sys/netinet6
Message-ID:  <201807032330.w63NUr6P074115@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: mmacy
Date: Tue Jul  3 23:30:53 2018
New Revision: 335919
URL: https://svnweb.freebsd.org/changeset/base/335919

Log:
  udp6_input: validate inpcb before use
  
  When traversing pcbinfo lists (rather than calling lookup) we need to
  explicitly validate an inpcb before use.

Modified:
  head/sys/netinet6/udp6_usrreq.c

Modified: head/sys/netinet6/udp6_usrreq.c
==============================================================================
--- head/sys/netinet6/udp6_usrreq.c	Tue Jul  3 23:29:18 2018	(r335918)
+++ head/sys/netinet6/udp6_usrreq.c	Tue Jul  3 23:30:53 2018	(r335919)
@@ -355,6 +355,10 @@ udp6_input(struct mbuf **mp, int *offp, int proto)
 				int			 blocked;
 
 				INP_RLOCK(inp);
+				if (__predict_false(inp->inp_flags2 & INP_FREED)) {
+					INP_RUNLOCK(inp);
+					continue;
+				}
 
 				bzero(&mcaddr, sizeof(struct sockaddr_in6));
 				mcaddr.sin6_len = sizeof(struct sockaddr_in6);
@@ -382,10 +386,12 @@ udp6_input(struct mbuf **mp, int *offp, int proto)
 				if ((n = m_copym(m, 0, M_COPYALL, M_NOWAIT)) !=
 				    NULL) {
 					INP_RLOCK(last);
-					UDP_PROBE(receive, NULL, last, ip6,
-					    last, uh);
-					if (udp6_append(last, n, off, fromsa))
-						goto inp_lost;
+					if (__predict_true(inp->inp_flags2 & INP_FREED) == 0) {
+						UDP_PROBE(receive, NULL, last, ip6,
+					        last, uh);
+						if (udp6_append(last, n, off, fromsa))
+							goto inp_lost;
+					}
 					INP_RUNLOCK(last);
 				}
 			}
@@ -414,10 +420,13 @@ udp6_input(struct mbuf **mp, int *offp, int proto)
 			goto badheadlocked;
 		}
 		INP_RLOCK(last);
-		INP_INFO_RUNLOCK(pcbinfo);
-		UDP_PROBE(receive, NULL, last, ip6, last, uh);
-		if (udp6_append(last, m, off, fromsa) == 0) 
+		if (__predict_true(inp->inp_flags2 & INP_FREED) == 0) {
+			UDP_PROBE(receive, NULL, last, ip6, last, uh);
+			if (udp6_append(last, m, off, fromsa) == 0)
+				INP_RUNLOCK(last);
+		} else
 			INP_RUNLOCK(last);
+		INP_INFO_RUNLOCK(pcbinfo);
 	inp_lost:
 		return (IPPROTO_DONE);
 	}



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