Commit b62c32db authored by Herbert Xu's avatar Herbert Xu Committed by David S. Miller

[IPSEC]: Check dst validity harder in xfrm_bundle_ok

There is another bug in xfrm_bundle_ok where I forgot to
check the validity of xdst->route.  In fact, the check
on dst->path isn't strong enough either.  For IPv6 entries,
dst->path->obsolete is always negative until you call
ipv6_dst_check.  So we really need to do that here.

Here's the patch to fix those two problems.  Yes I know
my dst_check implementation is lame.  I'll come back and
fix up all the dst_check functions by moving their dst_release
calls out.  It proves that you were right in that IPv6 dst
leak thread :)
Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 2160e348
...@@ -259,6 +259,15 @@ static inline int dst_input(struct sk_buff *skb) ...@@ -259,6 +259,15 @@ static inline int dst_input(struct sk_buff *skb)
} }
} }
static inline struct dst_entry *dst_check(struct dst_entry *dst, u32 cookie)
{
dst_hold(dst);
if (dst->obsolete)
dst = dst->ops->check(dst, cookie);
dst_release(dst);
return dst;
}
extern void dst_init(void); extern void dst_init(void);
struct flowi; struct flowi;
......
...@@ -1148,7 +1148,7 @@ int xfrm_bundle_ok(struct xfrm_dst *first, struct flowi *fl, int family) ...@@ -1148,7 +1148,7 @@ int xfrm_bundle_ok(struct xfrm_dst *first, struct flowi *fl, int family)
struct xfrm_dst *last; struct xfrm_dst *last;
u32 mtu; u32 mtu;
if (dst->path->obsolete > 0 || if (!dst_check(dst->path, 0) ||
(dst->dev && !netif_running(dst->dev))) (dst->dev && !netif_running(dst->dev)))
return 0; return 0;
...@@ -1168,6 +1168,8 @@ int xfrm_bundle_ok(struct xfrm_dst *first, struct flowi *fl, int family) ...@@ -1168,6 +1168,8 @@ int xfrm_bundle_ok(struct xfrm_dst *first, struct flowi *fl, int family)
xdst->child_mtu_cached = mtu; xdst->child_mtu_cached = mtu;
} }
if (!dst_check(xdst->route, 0))
return 0;
mtu = dst_pmtu(xdst->route); mtu = dst_pmtu(xdst->route);
if (xdst->route_mtu_cached != mtu) { if (xdst->route_mtu_cached != mtu) {
last = xdst; last = xdst;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment