lkml.org 
[lkml]   [2016]   [Nov]   [19]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4.4 12/37] fib_trie: Correct /proc/net/route off by one error
    Date
    4.4-stable review patch.  If anyone has any objections, please let me know.

    ------------------

    From: Alexander Duyck <alexander.h.duyck@intel.com>


    [ Upstream commit fd0285a39b1cb496f60210a9a00ad33a815603e7 ]

    The display of /proc/net/route has had a couple issues due to the fact that
    when I originally rewrote most of fib_trie I made it so that the iterator
    was tracking the next value to use instead of the current.

    In addition it had an off by 1 error where I was tracking the first piece
    of data as position 0, even though in reality that belonged to the
    SEQ_START_TOKEN.

    This patch updates the code so the iterator tracks the last reported
    position and key instead of the next expected position and key. In
    addition it shifts things so that all of the leaves start at 1 instead of
    trying to report leaves starting with offset 0 as being valid. With these
    two issues addressed this should resolve any off by one errors that were
    present in the display of /proc/net/route.

    Fixes: 25b97c016b26 ("ipv4: off-by-one in continuation handling in /proc/net/route")
    Cc: Andy Whitcroft <apw@canonical.com>
    Reported-by: Jason Baron <jbaron@akamai.com>
    Tested-by: Jason Baron <jbaron@akamai.com>
    Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com>
    Signed-off-by: David S. Miller <davem@davemloft.net>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
    ---
    net/ipv4/fib_trie.c | 21 +++++++++------------
    1 file changed, 9 insertions(+), 12 deletions(-)

    --- a/net/ipv4/fib_trie.c
    +++ b/net/ipv4/fib_trie.c
    @@ -2456,22 +2456,19 @@ static struct key_vector *fib_route_get_
    struct key_vector *l, **tp = &iter->tnode;
    t_key key;

    - /* use cache location of next-to-find key */
    + /* use cached location of previously found key */
    if (iter->pos > 0 && pos >= iter->pos) {
    - pos -= iter->pos;
    key = iter->key;
    } else {
    - iter->pos = 0;
    + iter->pos = 1;
    key = 0;
    }

    - while ((l = leaf_walk_rcu(tp, key)) != NULL) {
    + pos -= iter->pos;
    +
    + while ((l = leaf_walk_rcu(tp, key)) && (pos-- > 0)) {
    key = l->key + 1;
    iter->pos++;
    -
    - if (--pos <= 0)
    - break;
    -
    l = NULL;

    /* handle unlikely case of a key wrap */
    @@ -2480,7 +2477,7 @@ static struct key_vector *fib_route_get_
    }

    if (l)
    - iter->key = key; /* remember it */
    + iter->key = l->key; /* remember it */
    else
    iter->pos = 0; /* forget it */

    @@ -2508,7 +2505,7 @@ static void *fib_route_seq_start(struct
    return fib_route_get_idx(iter, *pos);

    iter->pos = 0;
    - iter->key = 0;
    + iter->key = KEY_MAX;

    return SEQ_START_TOKEN;
    }
    @@ -2517,7 +2514,7 @@ static void *fib_route_seq_next(struct s
    {
    struct fib_route_iter *iter = seq->private;
    struct key_vector *l = NULL;
    - t_key key = iter->key;
    + t_key key = iter->key + 1;

    ++*pos;

    @@ -2526,7 +2523,7 @@ static void *fib_route_seq_next(struct s
    l = leaf_walk_rcu(&iter->tnode, key);

    if (l) {
    - iter->key = l->key + 1;
    + iter->key = l->key;
    iter->pos++;
    } else {
    iter->pos = 0;

    \
     
     \ /
      Last update: 2016-11-19 10:41    [W:4.211 / U:0.232 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site