summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorbz <bz@FreeBSD.org>2010-10-23 20:35:40 +0000
committerbz <bz@FreeBSD.org>2010-10-23 20:35:40 +0000
commitde9392f9e014151a889a4d86de9f6736a94f158e (patch)
treef5d45570646bf96cfcb9125ee6a33290a6a158e2
parent1f7e8301f37d1383a1b54e2fd57a8f750ee42848 (diff)
downloadFreeBSD-src-de9392f9e014151a889a4d86de9f6736a94f158e.zip
FreeBSD-src-de9392f9e014151a889a4d86de9f6736a94f158e.tar.gz
Make the IPsec SADB embedded route cache a union to be able to hold both the
legacy and IPv6 route destination address. Previously in case of IPv6, there was a memory overwrite due to not enough space for the IPv6 address. PR: kern/122565 MFC After: 2 weeks
-rw-r--r--sys/netinet/ip_ipsec.c2
-rw-r--r--sys/netinet6/ip6_ipsec.c2
-rw-r--r--sys/netipsec/ipsec_output.c3
-rw-r--r--sys/netipsec/key.c8
-rw-r--r--sys/netipsec/keydb.h8
5 files changed, 15 insertions, 8 deletions
diff --git a/sys/netinet/ip_ipsec.c b/sys/netinet/ip_ipsec.c
index 3465d4b..50a6ce4 100644
--- a/sys/netinet/ip_ipsec.c
+++ b/sys/netinet/ip_ipsec.c
@@ -239,7 +239,7 @@ ip_ipsec_mtu(struct mbuf *m, int mtu)
if (sp->req != NULL &&
sp->req->sav != NULL &&
sp->req->sav->sah != NULL) {
- ro = &sp->req->sav->sah->sa_route;
+ ro = &sp->req->sav->sah->route_cache.sa_route;
if (ro->ro_rt && ro->ro_rt->rt_ifp) {
mtu =
ro->ro_rt->rt_rmx.rmx_mtu ?
diff --git a/sys/netinet6/ip6_ipsec.c b/sys/netinet6/ip6_ipsec.c
index 48d9162..96b09ef 100644
--- a/sys/netinet6/ip6_ipsec.c
+++ b/sys/netinet6/ip6_ipsec.c
@@ -366,7 +366,7 @@ ip6_ipsec_mtu(struct mbuf *m)
if (sp->req != NULL &&
sp->req->sav != NULL &&
sp->req->sav->sah != NULL) {
- ro = &sp->req->sav->sah->sa_route;
+ ro = &sp->req->sav->sah->route_cache.sa_route;
if (ro->ro_rt && ro->ro_rt->rt_ifp) {
mtu =
ro->ro_rt->rt_rmx.rmx_mtu ?
diff --git a/sys/netipsec/ipsec_output.c b/sys/netipsec/ipsec_output.c
index 2701796..0907f45 100644
--- a/sys/netipsec/ipsec_output.c
+++ b/sys/netipsec/ipsec_output.c
@@ -829,7 +829,8 @@ ipsec6_output_tunnel(struct ipsec_output_state *state, struct secpolicy *sp, int
}
ip6 = mtod(m, struct ip6_hdr *);
- state->ro = &isr->sav->sah->sa_route;
+ state->ro =
+ (struct route *)&isr->sav->sah->route_cache.sin6_route;
state->dst = (struct sockaddr *)&state->ro->ro_dst;
dst6 = (struct sockaddr_in6 *)state->dst;
if (state->ro->ro_rt
diff --git a/sys/netipsec/key.c b/sys/netipsec/key.c
index d00489d..e57eb44 100644
--- a/sys/netipsec/key.c
+++ b/sys/netipsec/key.c
@@ -2758,9 +2758,9 @@ key_delsah(sah)
/* remove from tree of SA index */
if (__LIST_CHAINED(sah))
LIST_REMOVE(sah, chain);
- if (sah->sa_route.ro_rt) {
- RTFREE(sah->sa_route.ro_rt);
- sah->sa_route.ro_rt = (struct rtentry *)NULL;
+ if (sah->route_cache.sa_route.ro_rt) {
+ RTFREE(sah->route_cache.sa_route.ro_rt);
+ sah->route_cache.sa_route.ro_rt = (struct rtentry *)NULL;
}
free(sah, M_IPSEC_SAH);
}
@@ -7925,7 +7925,7 @@ key_sa_routechange(dst)
SAHTREE_LOCK();
LIST_FOREACH(sah, &V_sahtree, chain) {
- ro = &sah->sa_route;
+ ro = &sah->route_cache.sa_route;
if (ro->ro_rt && dst->sa_len == ro->ro_dst.sa_len
&& bcmp(dst, &ro->ro_dst, dst->sa_len) == 0) {
RTFREE(ro->ro_rt);
diff --git a/sys/netipsec/keydb.h b/sys/netipsec/keydb.h
index 07e1f60..7494f5f 100644
--- a/sys/netipsec/keydb.h
+++ b/sys/netipsec/keydb.h
@@ -85,6 +85,12 @@ struct seclifetime {
u_int64_t usetime;
};
+union sa_route_union {
+ struct route sa_route;
+ struct route sin_route; /* Duplicate for consistency. */
+ struct route_in6 sin6_route;
+};
+
/* Security Association Data Base */
struct secashead {
LIST_ENTRY(secashead) chain;
@@ -100,7 +106,7 @@ struct secashead {
/* SA chain */
/* The first of this list is newer SA */
- struct route sa_route; /* route cache */
+ union sa_route_union route_cache;
};
struct xformsw;
OpenPOWER on IntegriCloud