diff options
author | bz <bz@FreeBSD.org> | 2010-10-23 20:35:40 +0000 |
---|---|---|
committer | bz <bz@FreeBSD.org> | 2010-10-23 20:35:40 +0000 |
commit | de9392f9e014151a889a4d86de9f6736a94f158e (patch) | |
tree | f5d45570646bf96cfcb9125ee6a33290a6a158e2 | |
parent | 1f7e8301f37d1383a1b54e2fd57a8f750ee42848 (diff) | |
download | FreeBSD-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.c | 2 | ||||
-rw-r--r-- | sys/netinet6/ip6_ipsec.c | 2 | ||||
-rw-r--r-- | sys/netipsec/ipsec_output.c | 3 | ||||
-rw-r--r-- | sys/netipsec/key.c | 8 | ||||
-rw-r--r-- | sys/netipsec/keydb.h | 8 |
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; |