Skip to content

Commit

Permalink
ipv6: compare sernum when walking fib for /proc/net/ipv6_route as saf…
Browse files Browse the repository at this point in the history
…ety net

This patch provides an additional safety net against NULL
pointer dereferences while walking the fib trie for the new
/proc/net/ipv6_route walkers. I never needed it myself and am unsure
if it is needed at all, but the same checks where introduced in
2bec5a3 ("ipv6: fib: fix crash when
changing large fib while dumping it") to fix NULL pointer bugs.

This patch is separated from the first patch to make it easier to revert
if we are sure we can drop this logic.

Cc: Ben Greear <greearb@candelatech.com>
Cc: Patrick McHardy <kaber@trash.net>
Cc: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
Signed-off-by: Hannes Frederic Sowa <hannes@stressinduktion.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Hannes Frederic Sowa authored and David S. Miller committed Sep 27, 2013
1 parent 8d2ca1d commit 0a67d3e
Showing 1 changed file with 14 additions and 0 deletions.
14 changes: 14 additions & 0 deletions net/ipv6/ip6_fib.c
Original file line number Diff line number Diff line change
Expand Up @@ -1771,6 +1771,7 @@ struct ipv6_route_iter {
struct fib6_walker_t w;
loff_t skip;
struct fib6_table *tbl;
__u32 sernum;
};

static int ipv6_route_seq_show(struct seq_file *seq, void *v)
Expand Down Expand Up @@ -1823,6 +1824,7 @@ static void ipv6_route_seq_setup_walk(struct ipv6_route_iter *iter)
iter->w.state = FWS_INIT;
iter->w.node = iter->w.root;
iter->w.args = iter;
iter->sernum = iter->w.root->fn_sernum;
INIT_LIST_HEAD(&iter->w.lh);
fib6_walker_link(&iter->w);
}
Expand All @@ -1848,6 +1850,17 @@ static struct fib6_table *ipv6_route_seq_next_table(struct fib6_table *tbl,
return hlist_entry_safe(node, struct fib6_table, tb6_hlist);
}

static void ipv6_route_check_sernum(struct ipv6_route_iter *iter)
{
if (iter->sernum != iter->w.root->fn_sernum) {
iter->sernum = iter->w.root->fn_sernum;
iter->w.state = FWS_INIT;
iter->w.node = iter->w.root;
WARN_ON(iter->w.skip);
iter->w.skip = iter->w.count;
}
}

static void *ipv6_route_seq_next(struct seq_file *seq, void *v, loff_t *pos)
{
int r;
Expand All @@ -1865,6 +1878,7 @@ static void *ipv6_route_seq_next(struct seq_file *seq, void *v, loff_t *pos)
}

iter_table:
ipv6_route_check_sernum(iter);
read_lock(&iter->tbl->tb6_lock);
r = fib6_walk_continue(&iter->w);
read_unlock(&iter->tbl->tb6_lock);
Expand Down

0 comments on commit 0a67d3e

Please sign in to comment.