linux-brain/net/sched
Sheng Lan 009510a90e net: netem: fix skb length BUG_ON in __skb_to_sgvec
[ Upstream commit 5845f70638 ]

It can be reproduced by following steps:
1. virtio_net NIC is configured with gso/tso on
2. configure nginx as http server with an index file bigger than 1M bytes
3. use tc netem to produce duplicate packets and delay:
   tc qdisc add dev eth0 root netem delay 100ms 10ms 30% duplicate 90%
4. continually curl the nginx http server to get index file on client
5. BUG_ON is seen quickly

[10258690.371129] kernel BUG at net/core/skbuff.c:4028!
[10258690.371748] invalid opcode: 0000 [#1] SMP PTI
[10258690.372094] CPU: 5 PID: 0 Comm: swapper/5 Tainted: G        W         5.0.0-rc6 #2
[10258690.372094] RSP: 0018:ffffa05797b43da0 EFLAGS: 00010202
[10258690.372094] RBP: 00000000000005ea R08: 0000000000000000 R09: 00000000000005ea
[10258690.372094] R10: ffffa0579334d800 R11: 00000000000002c0 R12: 0000000000000002
[10258690.372094] R13: 0000000000000000 R14: ffffa05793122900 R15: ffffa0578f7cb028
[10258690.372094] FS:  0000000000000000(0000) GS:ffffa05797b40000(0000) knlGS:0000000000000000
[10258690.372094] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[10258690.372094] CR2: 00007f1a6dc00868 CR3: 000000001000e000 CR4: 00000000000006e0
[10258690.372094] Call Trace:
[10258690.372094]  <IRQ>
[10258690.372094]  skb_to_sgvec+0x11/0x40
[10258690.372094]  start_xmit+0x38c/0x520 [virtio_net]
[10258690.372094]  dev_hard_start_xmit+0x9b/0x200
[10258690.372094]  sch_direct_xmit+0xff/0x260
[10258690.372094]  __qdisc_run+0x15e/0x4e0
[10258690.372094]  net_tx_action+0x137/0x210
[10258690.372094]  __do_softirq+0xd6/0x2a9
[10258690.372094]  irq_exit+0xde/0xf0
[10258690.372094]  smp_apic_timer_interrupt+0x74/0x140
[10258690.372094]  apic_timer_interrupt+0xf/0x20
[10258690.372094]  </IRQ>

In __skb_to_sgvec(), the skb->len is not equal to the sum of the skb's
linear data size and nonlinear data size, thus BUG_ON triggered.
Because the skb is cloned and a part of nonlinear data is split off.

Duplicate packet is cloned in netem_enqueue() and may be delayed
some time in qdisc. When qdisc len reached the limit and returns
NET_XMIT_DROP, the skb will be retransmit later in write queue.
the skb will be fragmented by tso_fragment(), the limit size
that depends on cwnd and mss decrease, the skb's nonlinear
data will be split off. The length of the skb cloned by netem
will not be updated. When we use virtio_net NIC and invoke skb_to_sgvec(),
the BUG_ON trigger.

To fix it, netem returns NET_XMIT_SUCCESS to upper stack
when it clones a duplicate packet.

Fixes: 35d889d1 ("sch_netem: fix skb leak in netem_enqueue()")
Signed-off-by: Sheng Lan <lansheng@huawei.com>
Reported-by: Qin Ji <jiqin.ji@huawei.com>
Suggested-by: Eric Dumazet <eric.dumazet@gmail.com>
Signed-off-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2019-03-13 14:04:53 -07:00
..
Kconfig net sched ife action: Introduce skb tcindex metadata encap decap 2016-09-19 21:55:28 -04:00
Makefile net sched ife action: Introduce skb tcindex metadata encap decap 2016-09-19 21:55:28 -04:00
act_api.c net sched actions: fix dumping which requires several messages to user space 2018-04-13 19:48:36 +02:00
act_bpf.c net/sched: fix NULL dereference in the error path of tcf_bpf_init() 2018-04-13 19:48:33 +02:00
act_connmark.c act_connmark: avoid crashing on malformed nlattrs with null parms 2017-03-22 12:43:34 +01:00
act_csum.c sched: act_csum: don't mangle TCP and UDP GSO packets 2018-03-22 09:17:42 +01:00
act_gact.c net/sched: Fix update of lastuse in act modules implementing stats_update 2018-01-17 09:38:54 +01:00
act_ife.c net: sched: action_ife: take reference to meta module 2018-09-15 09:42:56 +02:00
act_ipt.c net: sched: fix NULL pointer dereference when action calls some targets 2017-08-30 10:21:42 +02:00
act_meta_mark.c Support to encoding decoding skb mark on IFE action 2016-03-01 17:15:23 -05:00
act_meta_skbprio.c Support to encoding decoding skb prio on IFE action 2016-03-01 17:15:23 -05:00
act_meta_skbtcindex.c net sched ife action: Introduce skb tcindex metadata encap decap 2016-09-19 21:55:28 -04:00
act_mirred.c net/sched: Fix update of lastuse in act modules implementing stats_update 2018-01-17 09:38:54 +01:00
act_nat.c net_sched: move tc_action into tcf_common 2016-07-25 21:49:19 -07:00
act_pedit.c net/sched: pedit: make sure that offset is valid 2016-11-29 19:46:00 -05:00
act_police.c net sched: stylistic cleanups 2016-09-19 22:04:14 -04:00
act_simple.c net/sched: act_simple: fix parsing of TCA_DEF_DATA 2018-06-26 08:08:06 +08:00
act_skbedit.c net_sched: move tc_action into tcf_common 2016-07-25 21:49:19 -07:00
act_skbmod.c net/sched: fix NULL dereference on the error path of tcf_skbmod_init() 2018-04-13 19:48:35 +02:00
act_tunnel_key.c net/sched: act_tunnel_key: fix NULL dereference when 'goto chain' is used 2018-08-24 13:12:37 +02:00
act_vlan.c net/sched: act_vlan: Push skb->data to mac_header prior calling skb_vlan_*() functions 2016-10-03 21:40:50 -04:00
cls_api.c net, sched: fix soft lockup in tc_classify 2017-01-15 13:42:53 +01:00
cls_basic.c net, sched: respect rcu grace period on cls destruction 2016-11-28 10:47:35 -05:00
cls_bpf.c net, sched: respect rcu grace period on cls destruction 2016-11-28 10:47:35 -05:00
cls_cgroup.c net, sched: respect rcu grace period on cls destruction 2016-11-28 10:47:35 -05:00
cls_flow.c net, sched: respect rcu grace period on cls destruction 2016-11-28 10:47:35 -05:00
cls_flower.c net/sched: cls_flower: Fix missing addr_type in classify 2017-01-15 13:42:53 +01:00
cls_fw.c net sched: stylistic cleanups 2016-09-19 22:04:14 -04:00
cls_matchall.c cls_matchall: fix tcf_unbind_filter missing 2018-08-22 07:47:15 +02:00
cls_route.c net_sched: check NULL on error path in route4_change() 2016-09-23 06:51:49 -04:00
cls_rsvp.c
cls_rsvp.h net, sched: respect rcu grace period on cls destruction 2016-11-28 10:47:35 -05:00
cls_rsvp6.c
cls_tcindex.c net_sched: fix NULL pointer dereference when delete tcindex filter 2018-08-22 07:47:13 +02:00
cls_u32.c net: sched: Fix memory exposure from short TCA_U32_SEL 2018-09-15 09:42:55 +02:00
em_canid.c net: sched: remove tcf_proto from ematch calls 2014-10-06 18:02:32 -04:00
em_cmp.c net_sched: cleanups 2011-01-19 23:31:12 -08:00
em_ipset.c netfilter: x_tables: Pass struct net in xt_action_param 2015-09-18 21:58:14 +02:00
em_meta.c qdisc: constify meta_type_ops structures 2016-04-14 00:35:30 -04:00
em_nbyte.c net: sched: remove tcf_proto from ematch calls 2014-10-06 18:02:32 -04:00
em_text.c net: Remove state argument from skb_find_text() 2015-02-22 15:59:54 -05:00
em_u32.c net_sched: cleanups 2011-01-19 23:31:12 -08:00
ematch.c ematch: Fix auto-loading of ematch modules. 2015-02-20 15:30:56 -05:00
sch_api.c net_sched: refetch skb protocol for each filter 2019-01-31 08:12:33 +01:00
sch_atm.c net_sched: drop packets after root qdisc lock is released 2016-06-25 12:19:35 -04:00
sch_blackhole.c net_sched: blackhole: tell upper qdisc about dropped packets 2018-07-22 14:27:36 +02:00
sch_cbq.c net_sched: drop packets after root qdisc lock is released 2016-06-25 12:19:35 -04:00
sch_choke.c net_sched: red: Avoid illegal values 2018-02-25 11:05:48 +01:00
sch_codel.c sched: replace __skb_dequeue with __qdisc_dequeue_head 2016-09-19 01:47:18 -04:00
sch_drr.c net_sched: drop packets after root qdisc lock is released 2016-06-25 12:19:35 -04:00
sch_dsmark.c sch_dsmark: fix invalid skb_cow() usage 2017-12-25 14:23:38 +01:00
sch_fifo.c sched: don't use skb queue helpers 2016-09-19 01:47:18 -04:00
sch_fq.c net_sched: fq: take care of throttled flows before reuse 2018-05-19 10:26:58 +02:00
sch_fq_codel.c net_sched: fq_codel: cache skb->truesize into skb->cb 2016-06-25 12:19:35 -04:00
sch_generic.c net_sched: always reset qdisc backlog in qdisc_reset() 2017-10-12 11:51:22 +02:00
sch_gred.c net: sched: gred: pass the right attribute to gred_change_table_def() 2018-11-10 07:42:58 -08:00
sch_hfsc.c net/sched/sch_hfsc.c: remove unused cl_myfadj 2016-08-08 16:06:47 -07:00
sch_hhf.c sch_hhf: fix null pointer dereference on init failure 2018-09-15 09:43:06 +02:00
sch_htb.c sch_htb: fix crash on init failure 2018-09-15 09:43:02 +02:00
sch_ingress.c net: sched: fix tc_should_offload for specific clsact classes 2016-06-07 16:59:53 -07:00
sch_mq.c net_sched: fix error recovery at qdisc creation 2017-07-21 07:42:17 +02:00
sch_mqprio.c net_sched: fix error recovery at qdisc creation 2017-07-21 07:42:17 +02:00
sch_multiq.c sch_multiq: fix double free on init failure 2018-09-15 09:43:02 +02:00
sch_netem.c net: netem: fix skb length BUG_ON in __skb_to_sgvec 2019-03-13 14:04:53 -07:00
sch_pie.c sched: replace __skb_dequeue with __qdisc_dequeue_head 2016-09-19 01:47:18 -04:00
sch_plug.c net_sched: drop packets after root qdisc lock is released 2016-06-25 12:19:35 -04:00
sch_prio.c Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net 2016-06-30 05:03:36 -04:00
sch_qfq.c sch_qfq: keep backlog updated with qlen 2016-09-23 06:52:31 -04:00
sch_red.c net_sched: red: Avoid illegal values 2018-02-25 11:05:48 +01:00
sch_sfb.c sch_sfb: keep backlog updated with qlen 2016-09-23 06:52:31 -04:00
sch_sfq.c net_sched: red: Avoid illegal values 2018-02-25 11:05:48 +01:00
sch_tbf.c net: create skb_gso_validate_mac_len() 2019-02-20 10:18:28 +01:00
sch_teql.c net_sched: drop packets after root qdisc lock is released 2016-06-25 12:19:35 -04:00