PERFORCE change 38531 for review
Sam Leffler
sam at FreeBSD.org
Wed Sep 24 13:05:12 PDT 2003
http://perforce.freebsd.org/chv.cgi?CH=38531
Change 38531 by sam at 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;
More information about the p4-projects
mailing list