diff options
author | Eric Dumazet <eric.dumazet@gmail.com> | 2011-04-14 01:55:37 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2011-04-15 02:26:02 -0400 |
commit | c65353daf137dd41f3ede3baf62d561fca076228 (patch) | |
tree | 407488cc052fff615d61c889100a76e057c1f203 | |
parent | 49b4947aae404c8c5758ffd1007d0d78c48b3643 (diff) |
ip: ip_options_compile() resilient to NULL skb route
Scot Doyle demonstrated ip_options_compile() could be called with an skb
without an attached route, using a setup involving a bridge, netfilter,
and forged IP packets.
Let's make ip_options_compile() and ip_options_rcv_srr() a bit more
robust, instead of changing bridge/netfilter code.
With help from Hiroaki SHIMODA.
Reported-by: Scot Doyle <lkml@scotdoyle.com>
Tested-by: Scot Doyle <lkml@scotdoyle.com>
Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
Cc: Stephen Hemminger <shemminger@vyatta.com>
Acked-by: Hiroaki SHIMODA <shimoda.hiroaki@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | net/ipv4/ip_options.c | 6 |
1 files changed, 3 insertions, 3 deletions
diff --git a/net/ipv4/ip_options.c b/net/ipv4/ip_options.c index 28a736f3442f..2391b24e8251 100644 --- a/net/ipv4/ip_options.c +++ b/net/ipv4/ip_options.c | |||
@@ -329,7 +329,7 @@ int ip_options_compile(struct net *net, | |||
329 | pp_ptr = optptr + 2; | 329 | pp_ptr = optptr + 2; |
330 | goto error; | 330 | goto error; |
331 | } | 331 | } |
332 | if (skb) { | 332 | if (rt) { |
333 | memcpy(&optptr[optptr[2]-1], &rt->rt_spec_dst, 4); | 333 | memcpy(&optptr[optptr[2]-1], &rt->rt_spec_dst, 4); |
334 | opt->is_changed = 1; | 334 | opt->is_changed = 1; |
335 | } | 335 | } |
@@ -371,7 +371,7 @@ int ip_options_compile(struct net *net, | |||
371 | goto error; | 371 | goto error; |
372 | } | 372 | } |
373 | opt->ts = optptr - iph; | 373 | opt->ts = optptr - iph; |
374 | if (skb) { | 374 | if (rt) { |
375 | memcpy(&optptr[optptr[2]-1], &rt->rt_spec_dst, 4); | 375 | memcpy(&optptr[optptr[2]-1], &rt->rt_spec_dst, 4); |
376 | timeptr = (__be32*)&optptr[optptr[2]+3]; | 376 | timeptr = (__be32*)&optptr[optptr[2]+3]; |
377 | } | 377 | } |
@@ -603,7 +603,7 @@ int ip_options_rcv_srr(struct sk_buff *skb) | |||
603 | unsigned long orefdst; | 603 | unsigned long orefdst; |
604 | int err; | 604 | int err; |
605 | 605 | ||
606 | if (!opt->srr) | 606 | if (!opt->srr || !rt) |
607 | return 0; | 607 | return 0; |
608 | 608 | ||
609 | if (skb->pkt_type != PACKET_HOST) | 609 | if (skb->pkt_type != PACKET_HOST) |