aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/icmp.c
diff options
context:
space:
mode:
authorPatrick McHardy <kaber@trash.net>2007-05-19 17:44:15 -0400
committerDavid S. Miller <davem@davemloft.net>2007-05-19 17:44:15 -0400
commitd8cf27287ac7fb5cbfcc4139917a997c39d841ca (patch)
tree7882f48069e35c2a3c335997ecec08968bc474ef /net/ipv4/icmp.c
parent3ad2a6fb6bcc2f464cdde093a76b76b90b90c66c (diff)
[IPV4]: icmp: fix crash with sysctl_icmp_errors_use_inbound_ifaddr
When icmp_send is called on the local output path before the packet hits ip_output, skb->dev is not set, causing a crash when sysctl_icmp_errors_use_inbound_ifaddr is set. This can happen with the netfilter REJECT target or IPsec tunnels. Let routing decide the ICMP source address in that case, since the packet is locally generated there is no inbound interface and the sysctl should not apply. The option actually seems to be unfixable broken, on the path after ip_output() skb->dev points to the outgoing device and we don't know the incoming device anymore, so its going to do the absolute wrong thing and pick the address of the outgoing interface. Add a comment about this. Reported by Curtis Doty <Curtis@GreenKey.net>. Signed-off-by: Patrick McHardy <kaber@trash.net> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4/icmp.c')
-rw-r--r--net/ipv4/icmp.c5
1 files changed, 4 insertions, 1 deletions
diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c
index d38cbba92a4d..e238b17f554c 100644
--- a/net/ipv4/icmp.c
+++ b/net/ipv4/icmp.c
@@ -514,7 +514,10 @@ void icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info)
514 514
515 saddr = iph->daddr; 515 saddr = iph->daddr;
516 if (!(rt->rt_flags & RTCF_LOCAL)) { 516 if (!(rt->rt_flags & RTCF_LOCAL)) {
517 if (sysctl_icmp_errors_use_inbound_ifaddr) 517 /* This is broken, skb_in->dev points to the outgoing device
518 * after the packet passes through ip_output().
519 */
520 if (skb_in->dev && sysctl_icmp_errors_use_inbound_ifaddr)
518 saddr = inet_select_addr(skb_in->dev, 0, RT_SCOPE_LINK); 521 saddr = inet_select_addr(skb_in->dev, 0, RT_SCOPE_LINK);
519 else 522 else
520 saddr = 0; 523 saddr = 0;