Skip to content

Commit

Permalink
net: fib6: fib6_commit_metrics: fix potential NULL pointer dereference
Browse files Browse the repository at this point in the history
When IPv6 host routes with metrics attached are being added, we fetch
the metrics store from the dst via COW through dst_metrics_write_ptr(),
added through commit e5fd387.

One remaining problem here is that we actually call into inet_getpeer()
and may end up allocating/creating a new peer from the kmemcache, which
may fail.

Example trace from perf probe (inet_getpeer:41) where create is 1:

ip 6877 [002] 4221.391591: probe:inet_getpeer: (ffffffff8165e293)
  85e294 inet_getpeer.part.7 (<- kmem_cache_alloc())
  85e578 inet_getpeer
  8eb333 ipv6_cow_metrics
  8f10ff fib6_commit_metrics

Therefore, a check for NULL on the return of dst_metrics_write_ptr()
is necessary here.

Joint work with Florian Westphal.

Fixes: e5fd387 ("ipv6: do not overwrite inetpeer metrics prematurely")
Cc: Michal Kubeček <mkubecek@suse.cz>
Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Daniel Borkmann <dborkman@redhat.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Daniel Borkmann authored and David S. Miller committed Jan 6, 2015
1 parent 6cb6974 commit 0409c9a
Showing 1 changed file with 6 additions and 7 deletions.
13 changes: 6 additions & 7 deletions net/ipv6/ip6_fib.c
Original file line number Diff line number Diff line change
Expand Up @@ -633,18 +633,17 @@ static bool rt6_qualify_for_ecmp(struct rt6_info *rt)
static int fib6_commit_metrics(struct dst_entry *dst,
struct nlattr *mx, int mx_len)
{
bool dst_host = dst->flags & DST_HOST;
struct nlattr *nla;
int remaining;
u32 *mp;

if (dst->flags & DST_HOST) {
mp = dst_metrics_write_ptr(dst);
} else {
mp = kzalloc(sizeof(u32) * RTAX_MAX, GFP_ATOMIC);
if (!mp)
return -ENOMEM;
mp = dst_host ? dst_metrics_write_ptr(dst) :
kzalloc(sizeof(u32) * RTAX_MAX, GFP_ATOMIC);
if (unlikely(!mp))
return -ENOMEM;
if (!dst_host)
dst_init_metrics(dst, mp, 0);
}

nla_for_each_attr(nla, mx, mx_len, remaining) {
int type = nla_type(nla);
Expand Down

0 comments on commit 0409c9a

Please sign in to comment.