[RHEL7,COMMIT] ms/ipv6: fib6_rules should return exact return value

Submitted by Konstantin Khorenko on April 2, 2018, 2:45 p.m.

Details

Message ID 201804021445.w32Ej3Xv024938@finist_ce7.work
State New
Series "Handle IPv6 throw routes properly"
Headers show

Commit Message

Konstantin Khorenko April 2, 2018, 2:45 p.m.
The commit is pushed to "branch-rh7-3.10.0-693.21.1.vz7.46.x-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh7-3.10.0-693.21.1.vz7.46.2
------>
commit 0da0ad97c1417eaf48d95d7d7462baa3bff84745
Author: Hannes Frederic Sowa <hannes@stressinduktion.org>
Date:   Mon Apr 2 17:45:03 2018 +0300

    ms/ipv6: fib6_rules should return exact return value
    
    With the addition of the suppress operation
    (7764a45a8f1fe74d4f7d301eaca2e558e7e2831a ("fib_rules: add .suppress
    operation") we rely on accurate error reporting of the fib_rules.actions.
    
    fib6_rule_action always returned -EAGAIN in case we could not find a
    matching route and 0 if a rule was matched. This also included a match
    for blackhole or prohibited rule actions which could get suppressed by
    the new logic.
    
    So adapt fib6_rule_action to always return the correct error code as
    its counterpart fib4_rule_action does. This also fixes a possiblity of
    nullptr-deref where we don't find a table, thus rt == NULL. Because
    the condition rt != ip6_null_entry still holdes it seems we could later
    get a nullptr bug on dereference rt->dst.
    
    v2:
    a) Fixed a brain fart in the commit msg (the rule => a table, etc). No
       changes to the patch.
    
    Cc: Stefan Tomanek <stefan.tomanek@wertarbyte.de>
    Cc: Hideaki YOSHIFUJI <yoshfuji@linux-ipv6.org>
    Signed-off-by: Hannes Frederic Sowa <hannes@stressinduktion.org>
    Signed-off-by: David S. Miller <davem@davemloft.net>
    
    ms commit 46b3a421903aa2a4bc9731ca4663cee3ea869dab
    
    https://jira.sw.ru/browse/PSBM-81798
    Signed-off-by: Oleg Babin <obabin@virtuozzo.com>
    
    ============================
    Patchset description:
    Handle IPv6 throw routes properly
    
    IPv6 routing tables incorrectly handle routing rules for throw routes because
    error codes are not properly propagated up to the fib_rules_lookup().
    
    The issue is fixed in the mainline with the following two commits:
    
    Hannes Frederic Sowa (1):
      ms/ipv6: fib6_rules should return exact return value
    
    Steven Barth (1):
      ms/ipv6: fix backtracking for throw routes
---
 net/ipv6/fib6_rules.c | 14 +++++++++++---
 1 file changed, 11 insertions(+), 3 deletions(-)

Patch hide | download patch | download mbox

diff --git a/net/ipv6/fib6_rules.c b/net/ipv6/fib6_rules.c
index 9fc9b08c819e..aad7cd103186 100644
--- a/net/ipv6/fib6_rules.c
+++ b/net/ipv6/fib6_rules.c
@@ -66,26 +66,33 @@  static int fib6_rule_action(struct fib_rule *rule, struct flowi *flp,
 	struct fib6_table *table;
 	struct net *net = rule->fr_net;
 	pol_lookup_t lookup = arg->lookup_ptr;
+	int err = 0;
 
 	switch (rule->action) {
 	case FR_ACT_TO_TBL:
 		break;
 	case FR_ACT_UNREACHABLE:
+		err = -ENETUNREACH;
 		rt = net->ipv6.ip6_null_entry;
 		goto discard_pkt;
 	default:
 	case FR_ACT_BLACKHOLE:
+		err = -EINVAL;
 		rt = net->ipv6.ip6_blk_hole_entry;
 		goto discard_pkt;
 	case FR_ACT_PROHIBIT:
+		err = -EACCES;
 		rt = net->ipv6.ip6_prohibit_entry;
 		goto discard_pkt;
 	}
 
 	table = fib6_get_table(net, rule->table);
-	if (table)
-		rt = lookup(net, table, flp6, flags);
+	if (!table) {
+		err = -EAGAIN;
+		goto out;
+	}
 
+	rt = lookup(net, table, flp6, flags);
 	if (rt != net->ipv6.ip6_null_entry) {
 		struct fib6_rule *r = (struct fib6_rule *)rule;
 
@@ -112,6 +119,7 @@  static int fib6_rule_action(struct fib_rule *rule, struct flowi *flp,
 	}
 again:
 	ip6_rt_put(rt);
+	err = -EAGAIN;
 	rt = NULL;
 	goto out;
 
@@ -119,7 +127,7 @@  static int fib6_rule_action(struct fib_rule *rule, struct flowi *flp,
 	dst_hold(&rt->dst);
 out:
 	arg->result = rt;
-	return rt == NULL ? -EAGAIN : 0;
+	return err;
 }