diff options
author | Matti Vaittinen <matti.vaittinen@nsn.com> | 2011-11-16 16:18:02 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2011-11-17 03:16:25 -0500 |
commit | 14df015bb1708cd7ba1e5af11a1b0365b165a3ef (patch) | |
tree | 8b49170dec56070f9534905e7de7d1a3e682239a /net/ipv6 | |
parent | 8f5f69824fe221a36df781c2aee9fa1d74e89077 (diff) |
IPV6 Fix a crash when trying to replace non existing route
This patch fixes a crash when non existing IPv6 route is tried to be changed.
When new destination node was inserted in middle of FIB6 tree, no relevant
sanity checks were performed. Later route insertion might have been prevented
due to invalid request, causing node with no rt info being left in tree.
When this node was accessed, a crash occurred.
Patch adds missing checks in fib6_add_1()
Signed-off-by: Matti Vaittinen <Mazziesaccount@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv6')
-rw-r--r-- | net/ipv6/ip6_fib.c | 21 |
1 files changed, 14 insertions, 7 deletions
diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c index e8a0fcf8850a..e7b26dccd2d3 100644 --- a/net/ipv6/ip6_fib.c +++ b/net/ipv6/ip6_fib.c | |||
@@ -449,9 +449,15 @@ static struct fib6_node * fib6_add_1(struct fib6_node *root, void *addr, | |||
449 | */ | 449 | */ |
450 | if (plen < fn->fn_bit || | 450 | if (plen < fn->fn_bit || |
451 | !ipv6_prefix_equal(&key->addr, addr, fn->fn_bit)) { | 451 | !ipv6_prefix_equal(&key->addr, addr, fn->fn_bit)) { |
452 | if (!allow_create) | 452 | if (!allow_create) { |
453 | if (replace_required) { | ||
454 | printk(KERN_WARNING | ||
455 | "IPv6: Can't replace route, no match found\n"); | ||
456 | return ERR_PTR(-ENOENT); | ||
457 | } | ||
453 | printk(KERN_WARNING | 458 | printk(KERN_WARNING |
454 | "IPv6: NLM_F_CREATE should be set when creating new route\n"); | 459 | "IPv6: NLM_F_CREATE should be set when creating new route\n"); |
460 | } | ||
455 | goto insert_above; | 461 | goto insert_above; |
456 | } | 462 | } |
457 | 463 | ||
@@ -482,7 +488,7 @@ static struct fib6_node * fib6_add_1(struct fib6_node *root, void *addr, | |||
482 | fn = dir ? fn->right: fn->left; | 488 | fn = dir ? fn->right: fn->left; |
483 | } while (fn); | 489 | } while (fn); |
484 | 490 | ||
485 | if (replace_required && !allow_create) { | 491 | if (!allow_create) { |
486 | /* We should not create new node because | 492 | /* We should not create new node because |
487 | * NLM_F_REPLACE was specified without NLM_F_CREATE | 493 | * NLM_F_REPLACE was specified without NLM_F_CREATE |
488 | * I assume it is safe to require NLM_F_CREATE when | 494 | * I assume it is safe to require NLM_F_CREATE when |
@@ -492,16 +498,17 @@ static struct fib6_node * fib6_add_1(struct fib6_node *root, void *addr, | |||
492 | * MUST be specified if new route is created. | 498 | * MUST be specified if new route is created. |
493 | * That would keep IPv6 consistent with IPv4 | 499 | * That would keep IPv6 consistent with IPv4 |
494 | */ | 500 | */ |
495 | printk(KERN_WARNING | 501 | if (replace_required) { |
496 | "IPv6: NLM_F_CREATE should be set when creating new route - ignoring request\n"); | 502 | printk(KERN_WARNING |
497 | return ERR_PTR(-ENOENT); | 503 | "IPv6: Can't replace route, no match found\n"); |
504 | return ERR_PTR(-ENOENT); | ||
505 | } | ||
506 | printk(KERN_WARNING "IPv6: NLM_F_CREATE should be set when creating new route\n"); | ||
498 | } | 507 | } |
499 | /* | 508 | /* |
500 | * We walked to the bottom of tree. | 509 | * We walked to the bottom of tree. |
501 | * Create new leaf node without children. | 510 | * Create new leaf node without children. |
502 | */ | 511 | */ |
503 | if (!allow_create) | ||
504 | printk(KERN_WARNING "IPv6: NLM_F_CREATE should be set when creating new route\n"); | ||
505 | 512 | ||
506 | ln = node_alloc(); | 513 | ln = node_alloc(); |
507 | 514 | ||