Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 24 Sep 2003 13:05:10 -0700 (PDT)
From:      Sam Leffler <sam@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 38531 for review
Message-ID:  <200309242005.h8OK5ADC012627@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=38531

Change 38531 by sam@sam_ebb on 2003/09/24 13:05:04

	o hookup ipv4 ctlinput paths to a noop routine; we should be
	  handling path mtu changes at least
	o correct potential null pointer deref in ipsec4_common_input_cb

Affected files ...

.. //depot/projects/netperf/sys/netinet/in_proto.c#3 edit
.. //depot/projects/netperf/sys/netipsec/ipsec_input.c#6 edit
.. //depot/projects/netperf/sys/netipsec/ipsec_output.c#5 edit

Differences ...

==== //depot/projects/netperf/sys/netinet/in_proto.c#3 (text+ko) ====

@@ -160,13 +160,13 @@
 #endif /* IPSEC */
 #ifdef FAST_IPSEC
 { SOCK_RAW,	&inetdomain,	IPPROTO_AH,	PR_ATOMIC|PR_ADDR,
-  ah4_input,	0,	 	0,		0,
+  ah4_input,	0,	 	ah4_ctlinput,	0,
   0,	  
   0,		0,		0,		0,
   &nousrreqs
 },
 { SOCK_RAW,	&inetdomain,	IPPROTO_ESP,	PR_ATOMIC|PR_ADDR,
-  esp4_input,	0,	 	0,		0,
+  esp4_input,	0,	 	esp4_ctlinput,	0,
   0,	  
   0,		0,		0,		0,
   &nousrreqs

==== //depot/projects/netperf/sys/netipsec/ipsec_input.c#6 (text+ko) ====

@@ -94,6 +94,8 @@
 #define IPSEC_ISTAT(p,x,y,z) ((p) == IPPROTO_ESP ? (x)++ : \
 			    (p) == IPPROTO_AH ? (y)++ : (z)++)
 
+static void ipsec4_common_ctlinput(int, struct sockaddr *, void *, int);
+
 /*
  * ipsec_common_input gets called when an IPsec-protected packet
  * is received by IPv4 or IPv6.  It's job is to find the right SA
@@ -231,12 +233,26 @@
 {
 	ipsec4_common_input(m, off, IPPROTO_AH);
 }
+void
+ah4_ctlinput(int cmd, struct sockaddr *sa, void *v)
+{
+	if (sa->sa_family == AF_INET &&
+	    sa->sa_len == sizeof(struct sockaddr_in))
+		ipsec4_common_ctlinput(cmd, sa, v, IPPROTO_AH);
+}
 
 void
 esp4_input(struct mbuf *m, int off)
 {
 	ipsec4_common_input(m, off, IPPROTO_ESP);
 }
+void
+esp4_ctlinput(int cmd, struct sockaddr *sa, void *v)
+{
+	if (sa->sa_family == AF_INET &&
+	    sa->sa_len == sizeof(struct sockaddr_in))
+		ipsec4_common_ctlinput(cmd, sa, v, IPPROTO_ESP);
+}
 
 void
 ipcomp4_input(struct mbuf *m, int off)
@@ -444,6 +460,12 @@
 	m_freem(m);
 	return error;
 }
+
+void
+ipsec4_common_ctlinput(int cmd, struct sockaddr *sa, void *v, int proto)
+{
+	/* XXX nothing just yet */
+}
 #endif /* INET */
 
 #ifdef INET6
@@ -493,82 +515,6 @@
 	return IPPROTO_DONE;
 }
 
-void
-esp6_ctlinput(int cmd, struct sockaddr *sa, void *d)
-{
-	if (sa->sa_family != AF_INET6 ||
-	    sa->sa_len != sizeof(struct sockaddr_in6))
-		return;
-	if ((unsigned)cmd >= PRC_NCMDS)
-		return;
-
-	/* if the parameter is from icmp6, decode it. */
-	if (d !=  NULL) {
-		struct ip6ctlparam *ip6cp = (struct ip6ctlparam *)d;
-		struct mbuf *m = ip6cp->ip6c_m;
-		int off = ip6cp->ip6c_off;
-
-		struct ip6ctlparam ip6cp1;
-
-		/*
-		 * Notify the error to all possible sockets via pfctlinput2.
-		 * Since the upper layer information (such as protocol type,
-		 * source and destination ports) is embedded in the encrypted
-		 * data and might have been cut, we can't directly call
-		 * an upper layer ctlinput function. However, the pcbnotify
-		 * function will consider source and destination addresses
-		 * as well as the flow info value, and may be able to find
-		 * some PCB that should be notified.
-		 * Although pfctlinput2 will call esp6_ctlinput(), there is
-		 * no possibility of an infinite loop of function calls,
-		 * because we don't pass the inner IPv6 header.
-		 */
-		bzero(&ip6cp1, sizeof(ip6cp1));
-		ip6cp1.ip6c_src = ip6cp->ip6c_src;
-		pfctlinput2(cmd, sa, (void *)&ip6cp1);
-
-		/*
-		 * Then go to special cases that need ESP header information.
-		 * XXX: We assume that when ip6 is non NULL,
-		 * M and OFF are valid.
-		 */
-
-		if (cmd == PRC_MSGSIZE) {
-			struct secasvar *sav;
-			u_int32_t spi;
-			int valid;
-
-			/* check header length before using m_copydata */
-			if (m->m_pkthdr.len < off + sizeof (struct esp))
-				return;
-			m_copydata(m, off + offsetof(struct esp, esp_spi),
-				sizeof(u_int32_t), (caddr_t) &spi);
-			/*
-			 * Check to see if we have a valid SA corresponding to
-			 * the address in the ICMP message payload.
-			 */
-			sav = KEY_ALLOCSA((union sockaddr_union *)sa,
-					IPPROTO_ESP, spi);
-			valid = (sav != NULL);
-			if (sav)
-				KEY_FREESAV(&sav);
-
-			/* XXX Further validation? */
-
-			/*
-			 * Depending on whether the SA is "valid" and
-			 * routing table size (mtudisc_{hi,lo}wat), we will:
-			 * - recalcurate the new MTU and create the
-			 *   corresponding routing entry, or
-			 * - ignore the MTU change notification.
-			 */
-			icmp6_mtudisc_update(ip6cp, valid);
-		}
-	} else {
-		/* we normally notify any pcb here */
-	}
-}
-
 /*
  * IPsec input callback, called by the transform callback. Takes care of
  * filtering and other sanity checks on the processed packet.
@@ -738,7 +684,8 @@
 
 		m_tag_prepend(m, mtag);
 	} else {
-		mt->m_tag_id = PACKET_TAG_IPSEC_IN_DONE;
+		if (mt != NULL)
+			mt->m_tag_id = PACKET_TAG_IPSEC_IN_DONE;
 		/* XXX do we need to mark m_flags??? */
 	}
 
@@ -788,4 +735,80 @@
 		m_freem(m);
 	return error;
 }
+
+void
+esp6_ctlinput(int cmd, struct sockaddr *sa, void *d)
+{
+	if (sa->sa_family != AF_INET6 ||
+	    sa->sa_len != sizeof(struct sockaddr_in6))
+		return;
+	if ((unsigned)cmd >= PRC_NCMDS)
+		return;
+
+	/* if the parameter is from icmp6, decode it. */
+	if (d !=  NULL) {
+		struct ip6ctlparam *ip6cp = (struct ip6ctlparam *)d;
+		struct mbuf *m = ip6cp->ip6c_m;
+		int off = ip6cp->ip6c_off;
+
+		struct ip6ctlparam ip6cp1;
+
+		/*
+		 * Notify the error to all possible sockets via pfctlinput2.
+		 * Since the upper layer information (such as protocol type,
+		 * source and destination ports) is embedded in the encrypted
+		 * data and might have been cut, we can't directly call
+		 * an upper layer ctlinput function. However, the pcbnotify
+		 * function will consider source and destination addresses
+		 * as well as the flow info value, and may be able to find
+		 * some PCB that should be notified.
+		 * Although pfctlinput2 will call esp6_ctlinput(), there is
+		 * no possibility of an infinite loop of function calls,
+		 * because we don't pass the inner IPv6 header.
+		 */
+		bzero(&ip6cp1, sizeof(ip6cp1));
+		ip6cp1.ip6c_src = ip6cp->ip6c_src;
+		pfctlinput2(cmd, sa, (void *)&ip6cp1);
+
+		/*
+		 * Then go to special cases that need ESP header information.
+		 * XXX: We assume that when ip6 is non NULL,
+		 * M and OFF are valid.
+		 */
+
+		if (cmd == PRC_MSGSIZE) {
+			struct secasvar *sav;
+			u_int32_t spi;
+			int valid;
+
+			/* check header length before using m_copydata */
+			if (m->m_pkthdr.len < off + sizeof (struct esp))
+				return;
+			m_copydata(m, off + offsetof(struct esp, esp_spi),
+				sizeof(u_int32_t), (caddr_t) &spi);
+			/*
+			 * Check to see if we have a valid SA corresponding to
+			 * the address in the ICMP message payload.
+			 */
+			sav = KEY_ALLOCSA((union sockaddr_union *)sa,
+					IPPROTO_ESP, spi);
+			valid = (sav != NULL);
+			if (sav)
+				KEY_FREESAV(&sav);
+
+			/* XXX Further validation? */
+
+			/*
+			 * Depending on whether the SA is "valid" and
+			 * routing table size (mtudisc_{hi,lo}wat), we will:
+			 * - recalcurate the new MTU and create the
+			 *   corresponding routing entry, or
+			 * - ignore the MTU change notification.
+			 */
+			icmp6_mtudisc_update(ip6cp, valid);
+		}
+	} else {
+		/* we normally notify any pcb here */
+	}
+}
 #endif /* INET6 */

==== //depot/projects/netperf/sys/netipsec/ipsec_output.c#5 (text+ko) ====

@@ -347,7 +347,7 @@
 	IPSEC_ASSERT(m != NULL, ("null mbuf"));
 	IPSEC_ASSERT(isr != NULL, ("null isr"));
 
-	mtx_lock(&isr->lock);		/* insure SA contents don't change */
+	IPSECREQUEST_LOCK(isr);		/* insure SA contents don't change */
 
 	isr = ipsec_nextisr(m, isr, AF_INET, &saidx, &error);
 	if (isr == NULL)
@@ -466,10 +466,10 @@
 	} else {
 		error = ipsec_process_done(m, isr);
 	}
-	mtx_unlock(&isr->lock);
+	IPSECREQUEST_UNLOCK(isr);
 	return error;
 bad:
-	mtx_unlock(&isr->lock);
+	IPSECREQUEST_UNLOCK(isr);
 	if (m)
 		m_freem(m);
 	return error;



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