diff options
author | David S. Miller <davem@davemloft.net> | 2012-07-05 03:13:17 +0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2012-07-05 03:13:17 +0400 |
commit | 11604721a3c4bea60e2ddd9e4e30d741ecdba7b0 (patch) | |
tree | cfc0f846bdfc9e146398133f6beec39b6e255b4c | |
parent | e87183c2b5ab1f55ebad2f260a7eb4d31549ce25 (diff) | |
download | linux-11604721a3c4bea60e2ddd9e4e30d741ecdba7b0.tar.xz |
ipv4: Fix crashes in ip_options_compile().
The spec_dst uses should be guarded by skb_rtable() being non-NULL
not just the SKB being non-null.
Reported-by: Eric Dumazet <eric.dumazet@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | net/ipv4/ip_options.c | 9 |
1 files changed, 6 insertions, 3 deletions
diff --git a/net/ipv4/ip_options.c b/net/ipv4/ip_options.c index 766dfe56885a..1f022510abe3 100644 --- a/net/ipv4/ip_options.c +++ b/net/ipv4/ip_options.c @@ -253,12 +253,15 @@ int ip_options_compile(struct net *net, { __be32 spec_dst = (__force __be32) 0; unsigned char *pp_ptr = NULL; + struct rtable *rt = NULL; unsigned char *optptr; unsigned char *iph; int optlen, l; if (skb != NULL) { - spec_dst = fib_compute_spec_dst(skb); + rt = skb_rtable(skb); + if (rt) + spec_dst = fib_compute_spec_dst(skb); optptr = (unsigned char *)&(ip_hdr(skb)[1]); } else optptr = opt->__data; @@ -330,7 +333,7 @@ int ip_options_compile(struct net *net, pp_ptr = optptr + 2; goto error; } - if (skb) { + if (rt) { memcpy(&optptr[optptr[2]-1], &spec_dst, 4); opt->is_changed = 1; } @@ -372,7 +375,7 @@ int ip_options_compile(struct net *net, goto error; } opt->ts = optptr - iph; - if (skb) { + if (rt) { memcpy(&optptr[optptr[2]-1], &spec_dst, 4); timeptr = &optptr[optptr[2]+3]; } |