mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-10-04 08:08:54 +00:00
[IPV6] ROUTE: Fix looking up a route on subtree.
Even on RTN_ROOT node, we need to process its subtree first. Fix NULL pointer dereference in fib6_locate(). Based on MIPL2 kernel patch. Signed-off-by: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org> Signed-off-by: Ville Nuorvala <vnuorval@tcs.hut.fi> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
2285adc1e6
commit
3fc5e0440b
1 changed files with 15 additions and 24 deletions
|
@ -850,33 +850,26 @@ static struct fib6_node * fib6_lookup_1(struct fib6_node *root,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
while ((fn->fn_flags & RTN_ROOT) == 0) {
|
while(fn) {
|
||||||
#ifdef CONFIG_IPV6_SUBTREES
|
if (SUBTREE(fn) || fn->fn_flags & RTN_RTINFO) {
|
||||||
if (fn->subtree) {
|
|
||||||
struct fib6_node *st;
|
|
||||||
struct lookup_args *narg;
|
|
||||||
|
|
||||||
narg = args + 1;
|
|
||||||
|
|
||||||
if (narg->addr) {
|
|
||||||
st = fib6_lookup_1(fn->subtree, narg);
|
|
||||||
|
|
||||||
if (st && !(st->fn_flags & RTN_ROOT))
|
|
||||||
return st;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (fn->fn_flags & RTN_RTINFO) {
|
|
||||||
struct rt6key *key;
|
struct rt6key *key;
|
||||||
|
|
||||||
key = (struct rt6key *) ((u8 *) fn->leaf +
|
key = (struct rt6key *) ((u8 *) fn->leaf +
|
||||||
args->offset);
|
args->offset);
|
||||||
|
|
||||||
if (ipv6_prefix_equal(&key->addr, args->addr, key->plen))
|
if (ipv6_prefix_equal(&key->addr, args->addr, key->plen)) {
|
||||||
return fn;
|
#ifdef CONFIG_IPV6_SUBTREES
|
||||||
|
if (fn->subtree)
|
||||||
|
fn = fib6_lookup_1(fn->subtree, args + 1);
|
||||||
|
#endif
|
||||||
|
if (!fn || fn->fn_flags & RTN_RTINFO)
|
||||||
|
return fn;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (fn->fn_flags & RTN_ROOT)
|
||||||
|
break;
|
||||||
|
|
||||||
fn = fn->parent;
|
fn = fn->parent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -953,10 +946,8 @@ struct fib6_node * fib6_locate(struct fib6_node *root,
|
||||||
#ifdef CONFIG_IPV6_SUBTREES
|
#ifdef CONFIG_IPV6_SUBTREES
|
||||||
if (src_len) {
|
if (src_len) {
|
||||||
BUG_TRAP(saddr!=NULL);
|
BUG_TRAP(saddr!=NULL);
|
||||||
if (fn == NULL)
|
if (fn && fn->subtree)
|
||||||
fn = fn->subtree;
|
fn = fib6_locate_1(fn->subtree, saddr, src_len,
|
||||||
if (fn)
|
|
||||||
fn = fib6_locate_1(fn, saddr, src_len,
|
|
||||||
offsetof(struct rt6_info, rt6i_src));
|
offsetof(struct rt6_info, rt6i_src));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in a new issue