linux-stable/net/ipv6
Daniel Borkmann 4c672e4b42 ipv6: mld: fix add_grhead skb_over_panic for devs with large MTUs
It has been reported that generating an MLD listener report on
devices with large MTUs (e.g. 9000) and a high number of IPv6
addresses can trigger a skb_over_panic():

skbuff: skb_over_panic: text:ffffffff80612a5d len:3776 put:20
head:ffff88046d751000 data:ffff88046d751010 tail:0xed0 end:0xec0
dev:port1
 ------------[ cut here ]------------
kernel BUG at net/core/skbuff.c:100!
invalid opcode: 0000 [#1] SMP
Modules linked in: ixgbe(O)
CPU: 3 PID: 0 Comm: swapper/3 Tainted: G O 3.14.23+ #4
[...]
Call Trace:
 <IRQ>
 [<ffffffff80578226>] ? skb_put+0x3a/0x3b
 [<ffffffff80612a5d>] ? add_grhead+0x45/0x8e
 [<ffffffff80612e3a>] ? add_grec+0x394/0x3d4
 [<ffffffff80613222>] ? mld_ifc_timer_expire+0x195/0x20d
 [<ffffffff8061308d>] ? mld_dad_timer_expire+0x45/0x45
 [<ffffffff80255b5d>] ? call_timer_fn.isra.29+0x12/0x68
 [<ffffffff80255d16>] ? run_timer_softirq+0x163/0x182
 [<ffffffff80250e6f>] ? __do_softirq+0xe0/0x21d
 [<ffffffff8025112b>] ? irq_exit+0x4e/0xd3
 [<ffffffff802214bb>] ? smp_apic_timer_interrupt+0x3b/0x46
 [<ffffffff8063f10a>] ? apic_timer_interrupt+0x6a/0x70

mld_newpack() skb allocations are usually requested with dev->mtu
in size, since commit 72e09ad107 ("ipv6: avoid high order allocations")
we have changed the limit in order to be less likely to fail.

However, in MLD/IGMP code, we have some rather ugly AVAILABLE(skb)
macros, which determine if we may end up doing an skb_put() for
adding another record. To avoid possible fragmentation, we check
the skb's tailroom as skb->dev->mtu - skb->len, which is a wrong
assumption as the actual max allocation size can be much smaller.

The IGMP case doesn't have this issue as commit 57e1ab6ead
("igmp: refine skb allocations") stores the allocation size in
the cb[].

Set a reserved_tailroom to make it fit into the MTU and use
skb_availroom() helper instead. This also allows to get rid of
igmp_skb_size().

Reported-by: Wei Liu <lw1a2.jing@gmail.com>
Fixes: 72e09ad107 ("ipv6: avoid high order allocations")
Signed-off-by: Daniel Borkmann <dborkman@redhat.com>
Cc: Eric Dumazet <edumazet@google.com>
Cc: Hannes Frederic Sowa <hannes@stressinduktion.org>
Cc: David L Stevens <david.stevens@oracle.com>
Acked-by: Eric Dumazet <edumazet@google.com>
Acked-by: Hannes Frederic Sowa <hannes@stressinduktion.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
2014-11-05 22:12:30 -05:00
..
netfilter netfilter: nf_reject_ipv6: split nf_send_reset6() in smaller functions 2014-10-31 12:49:57 +01:00
addrconf.c Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net 2014-11-01 14:53:27 -04:00
addrconf_core.c ipv6: remove rt6i_genid 2014-09-30 14:00:48 -04:00
addrlabel.c list: fix order of arguments for hlist_add_after(_rcu) 2014-08-06 18:01:24 -07:00
af_inet6.c ipv6: make fib6 serial number per namespace 2014-10-07 00:02:30 -04:00
ah6.c ipsec: Remove obsolete MAX_AH_AUTH_LEN 2014-09-18 10:54:36 +02:00
anycast.c ipv6: remove aca_lock spinlock from struct ifacaddr6 2014-10-14 13:15:15 -04:00
datagram.c net: Add and use skb_copy_datagram_msg() helper. 2014-11-05 16:46:40 -05:00
esp6.c ipv6: White-space cleansing : Structure layouts 2014-08-24 22:37:52 -07:00
exthdrs.c ipv6: include linux/uaccess.h instead of asm/uaccess.h 2014-10-27 16:03:52 -04:00
exthdrs_core.c ipv6: ipv6_find_hdr restore prev functionality 2014-02-27 18:27:26 -05:00
exthdrs_offload.c ipv6: Fix exthdrs offload registration. 2014-03-06 16:35:55 -05:00
fib6_rules.c ipv6: move IPV6_TCLASS_SHIFT into ipv6.h and define a helper 2014-01-15 15:53:18 -08:00
icmp.c net: Remove trailing whitespace in tcp.h icmp.c syncookies.c 2014-10-24 00:13:10 -04:00
inet6_connection_sock.c ipv6: White-space cleansing : gaps between function and symbol export 2014-08-24 22:37:52 -07:00
inet6_hashtables.c ipv6: White-space cleansing : gaps between function and symbol export 2014-08-24 22:37:52 -07:00
ip6_checksum.c udp: Generic functions to set checksum 2014-06-04 22:46:38 -07:00
ip6_fib.c ipv6: don't walk node's leaf during serial number update 2014-10-07 00:02:30 -04:00
ip6_flowlabel.c net: Convert SEQ_START_TOKEN/seq_printf to seq_puts 2014-11-05 22:04:55 -05:00
ip6_gre.c Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net 2014-10-08 16:22:22 -04:00
ip6_icmp.c ipv6: White-space cleansing : Line Layouts 2014-08-24 22:37:52 -07:00
ip6_input.c ipv6: White-space cleansing : Line Layouts 2014-08-24 22:37:52 -07:00
ip6_offload.c udp: Changes to udp_offload to support remote checksum offload 2014-11-05 16:30:03 -05:00
ip6_offload.h
ip6_output.c Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net 2014-09-23 12:09:27 -04:00
ip6_tunnel.c ip6_tunnel: allow to change mode for the ip6tnl0 2014-10-30 16:09:20 -04:00
ip6_udp_tunnel.c udp: Need to make ip6_udp_tunnel.c have GPL license 2014-09-22 15:08:25 -04:00
ip6_vti.c net: better IFF_XMIT_DST_RELEASE support 2014-10-07 13:22:11 -04:00
ip6mr.c ipv6: spelling s/incomming/incoming 2014-10-30 15:51:43 -04:00
ipcomp6.c ipv6: White-space cleansing : Structure layouts 2014-08-24 22:37:52 -07:00
ipv6_sockglue.c ipv6: White-space cleansing : gaps between function and symbol export 2014-08-24 22:37:52 -07:00
Kconfig ip6_vti: Fix build when NET_IP_TUNNEL is not set. 2014-02-20 14:29:49 +01:00
Makefile udp_tunnel: Only build ip6_udp_tunnel.c when IPV6 is selected 2014-09-19 22:05:28 -04:00
mcast.c ipv6: mld: fix add_grhead skb_over_panic for devs with large MTUs 2014-11-05 22:12:30 -05:00
mip6.c ipv6: White-space cleansing : Structure layouts 2014-08-24 22:37:52 -07:00
ndisc.c ipv6: White-space cleansing : gaps between function and symbol export 2014-08-24 22:37:52 -07:00
netfilter.c netfilter: Fix potential use after free in ip6_route_me_harder() 2014-05-09 02:36:39 +02:00
output_core.c drivers/net, ipv6: Select IPv6 fragment idents for virtio UFO packets 2014-10-30 20:01:18 -04:00
ping.c net: Eliminate no_check from protosw 2014-05-23 16:28:53 -04:00
proc.c ipv6: White-space cleansing : Line Layouts 2014-08-24 22:37:52 -07:00
protocol.c net: Export inet_offloads and inet6_offloads 2014-09-19 17:15:31 -04:00
raw.c net: Add and use skb_copy_datagram_msg() helper. 2014-11-05 16:46:40 -05:00
reassembly.c ipv6: remove inline on static in c file 2014-10-30 15:51:43 -04:00
route.c ipv6: Avoid redoing fib6_lookup() with reachable = 0 by saving fn 2014-10-24 00:14:39 -04:00
sit.c ipv6: fix a potential use after free in sit.c 2014-10-18 13:04:09 -04:00
syncookies.c net: allow setting ecn via routing table 2014-11-04 16:06:09 -05:00
sysctl_net_ipv6.c ipv6: add sysctl_mld_qrv to configure query robustness variable 2014-09-04 22:26:14 -07:00
tcp_ipv6.c net: fix saving TX flow hash in sock for outgoing connections 2014-10-22 16:14:29 -04:00
tcpv6_offload.c net: Remove gso_send_check as an offload callback 2014-09-26 00:22:47 -04:00
tunnel6.c ipv6: White-space cleansing : gaps between function and symbol export 2014-08-24 22:37:52 -07:00
udp.c net: Add and use skb_copy_datagram_msg() helper. 2014-11-05 16:46:40 -05:00
udp_impl.h net: ipv4/ipv6: Remove extern from function prototypes 2013-10-19 19:12:11 -04:00
udp_offload.c udp: Changes to udp_offload to support remote checksum offload 2014-11-05 16:30:03 -05:00
udplite.c net: Eliminate no_check from protosw 2014-05-23 16:28:53 -04:00
xfrm6_input.c ipv6: White-space cleansing : gaps between function and symbol export 2014-08-24 22:37:52 -07:00
xfrm6_mode_beet.c
xfrm6_mode_ro.c ipv4/ipv6: Fix FSF address in file headers 2013-12-06 12:37:56 -05:00
xfrm6_mode_transport.c
xfrm6_mode_tunnel.c xfrm6: Remove xfrm_tunnel_notifier 2014-03-14 07:28:08 +01:00
xfrm6_output.c ipv6: White-space cleansing : gaps between function and symbol export 2014-08-24 22:37:52 -07:00
xfrm6_policy.c xfrm6: fix a potential use after free in xfrm6_policy.c 2014-10-22 15:38:48 -04:00
xfrm6_protocol.c xfrm6: Properly handle unsupported protocols 2014-05-06 07:08:38 +02:00
xfrm6_state.c ipv6: White-space cleansing : Line Layouts 2014-08-24 22:37:52 -07:00
xfrm6_tunnel.c ipv6: White-space cleansing : gaps between function and symbol export 2014-08-24 22:37:52 -07:00