linux-stable/net/sched
Tao Liu 0b5b831122 net/sched: act_ct: fix skb leak and crash on ooo frags
[ Upstream commit 3f14b377d0 ]

act_ct adds skb->users before defragmentation. If frags arrive in order,
the last frag's reference is reset in:

  inet_frag_reasm_prepare
    skb_morph

which is not straightforward.

However when frags arrive out of order, nobody unref the last frag, and
all frags are leaked. The situation is even worse, as initiating packet
capture can lead to a crash[0] when skb has been cloned and shared at the
same time.

Fix the issue by removing skb_get() before defragmentation. act_ct
returns TC_ACT_CONSUMED when defrag failed or in progress.

[0]:
[  843.804823] ------------[ cut here ]------------
[  843.809659] kernel BUG at net/core/skbuff.c:2091!
[  843.814516] invalid opcode: 0000 [#1] PREEMPT SMP
[  843.819296] CPU: 7 PID: 0 Comm: swapper/7 Kdump: loaded Tainted: G S 6.7.0-rc3 #2
[  843.824107] Hardware name: XFUSION 1288H V6/BC13MBSBD, BIOS 1.29 11/25/2022
[  843.828953] RIP: 0010:pskb_expand_head+0x2ac/0x300
[  843.833805] Code: 8b 70 28 48 85 f6 74 82 48 83 c6 08 bf 01 00 00 00 e8 38 bd ff ff 8b 83 c0 00 00 00 48 03 83 c8 00 00 00 e9 62 ff ff ff 0f 0b <0f> 0b e8 8d d0 ff ff e9 b3 fd ff ff 81 7c 24 14 40 01 00 00 4c 89
[  843.843698] RSP: 0018:ffffc9000cce07c0 EFLAGS: 00010202
[  843.848524] RAX: 0000000000000002 RBX: ffff88811a211d00 RCX: 0000000000000820
[  843.853299] RDX: 0000000000000640 RSI: 0000000000000000 RDI: ffff88811a211d00
[  843.857974] RBP: ffff888127d39518 R08: 00000000bee97314 R09: 0000000000000000
[  843.862584] R10: 0000000000000000 R11: ffff8881109f0000 R12: 0000000000000880
[  843.867147] R13: ffff888127d39580 R14: 0000000000000640 R15: ffff888170f7b900
[  843.871680] FS:  0000000000000000(0000) GS:ffff889ffffc0000(0000) knlGS:0000000000000000
[  843.876242] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[  843.880778] CR2: 00007fa42affcfb8 CR3: 000000011433a002 CR4: 0000000000770ef0
[  843.885336] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
[  843.889809] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
[  843.894229] PKRU: 55555554
[  843.898539] Call Trace:
[  843.902772]  <IRQ>
[  843.906922]  ? __die_body+0x1e/0x60
[  843.911032]  ? die+0x3c/0x60
[  843.915037]  ? do_trap+0xe2/0x110
[  843.918911]  ? pskb_expand_head+0x2ac/0x300
[  843.922687]  ? do_error_trap+0x65/0x80
[  843.926342]  ? pskb_expand_head+0x2ac/0x300
[  843.929905]  ? exc_invalid_op+0x50/0x60
[  843.933398]  ? pskb_expand_head+0x2ac/0x300
[  843.936835]  ? asm_exc_invalid_op+0x1a/0x20
[  843.940226]  ? pskb_expand_head+0x2ac/0x300
[  843.943580]  inet_frag_reasm_prepare+0xd1/0x240
[  843.946904]  ip_defrag+0x5d4/0x870
[  843.950132]  nf_ct_handle_fragments+0xec/0x130 [nf_conntrack]
[  843.953334]  tcf_ct_act+0x252/0xd90 [act_ct]
[  843.956473]  ? tcf_mirred_act+0x516/0x5a0 [act_mirred]
[  843.959657]  tcf_action_exec+0xa1/0x160
[  843.962823]  fl_classify+0x1db/0x1f0 [cls_flower]
[  843.966010]  ? skb_clone+0x53/0xc0
[  843.969173]  tcf_classify+0x24d/0x420
[  843.972333]  tc_run+0x8f/0xf0
[  843.975465]  __netif_receive_skb_core+0x67a/0x1080
[  843.978634]  ? dev_gro_receive+0x249/0x730
[  843.981759]  __netif_receive_skb_list_core+0x12d/0x260
[  843.984869]  netif_receive_skb_list_internal+0x1cb/0x2f0
[  843.987957]  ? mlx5e_handle_rx_cqe_mpwrq_rep+0xfa/0x1a0 [mlx5_core]
[  843.991170]  napi_complete_done+0x72/0x1a0
[  843.994305]  mlx5e_napi_poll+0x28c/0x6d0 [mlx5_core]
[  843.997501]  __napi_poll+0x25/0x1b0
[  844.000627]  net_rx_action+0x256/0x330
[  844.003705]  __do_softirq+0xb3/0x29b
[  844.006718]  irq_exit_rcu+0x9e/0xc0
[  844.009672]  common_interrupt+0x86/0xa0
[  844.012537]  </IRQ>
[  844.015285]  <TASK>
[  844.017937]  asm_common_interrupt+0x26/0x40
[  844.020591] RIP: 0010:acpi_safe_halt+0x1b/0x20
[  844.023247] Code: ff 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 40 00 65 48 8b 04 25 00 18 03 00 48 8b 00 a8 08 75 0c 66 90 0f 00 2d 81 d0 44 00 fb f4 <fa> c3 0f 1f 00 89 fa ec 48 8b 05 ee 88 ed 00 a9 00 00 00 80 75 11
[  844.028900] RSP: 0018:ffffc90000533e70 EFLAGS: 00000246
[  844.031725] RAX: 0000000000004000 RBX: 0000000000000001 RCX: 0000000000000000
[  844.034553] RDX: ffff889ffffc0000 RSI: ffffffff828b7f20 RDI: ffff88a090f45c64
[  844.037368] RBP: ffff88a0901a2800 R08: ffff88a090f45c00 R09: 00000000000317c0
[  844.040155] R10: 00ec812281150475 R11: ffff889fffff0e04 R12: ffffffff828b7fa0
[  844.042962] R13: ffffffff828b7f20 R14: 0000000000000001 R15: 0000000000000000
[  844.045819]  acpi_idle_enter+0x7b/0xc0
[  844.048621]  cpuidle_enter_state+0x7f/0x430
[  844.051451]  cpuidle_enter+0x2d/0x40
[  844.054279]  do_idle+0x1d4/0x240
[  844.057096]  cpu_startup_entry+0x2a/0x30
[  844.059934]  start_secondary+0x104/0x130
[  844.062787]  secondary_startup_64_no_verify+0x16b/0x16b
[  844.065674]  </TASK>

Fixes: b57dc7c13e ("net/sched: Introduce action ct")
Signed-off-by: Tao Liu <taoliu828@163.com>
Link: https://lore.kernel.org/r/20231228081457.936732-1-taoliu828@163.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
2024-01-25 15:27:31 -08:00
..
act_api.c net/sched: act_api: add specific EXT_WARN_MSG for tc action 2023-06-21 16:01:02 +02:00
act_bpf.c net: sched: act_bpf: simplify code logic in tcf_bpf_init() 2022-09-28 09:38:56 +01:00
act_connmark.c netfilter: conntrack: Fix data-races around ct mark 2022-11-18 15:21:00 +01:00
act_csum.c net: sched: act_csum: get rid of tcf_csum_walker and tcf_csum_search 2022-09-09 08:24:41 +01:00
act_ct.c net/sched: act_ct: fix skb leak and crash on ooo frags 2024-01-25 15:27:31 -08:00
act_ctinfo.c net/sched: act_ctinfo: use percpu stats 2023-02-22 12:59:52 +01:00
act_gact.c treewide: use prandom_u32_max() when possible, part 1 2022-10-11 17:42:55 -06:00
act_gate.c net: sched: act_gate: get rid of tcf_gate_walker and tcf_gate_search 2022-09-09 08:24:42 +01:00
act_ife.c net: sched: act_ife: get rid of tcf_ife_walker and tcf_ife_search 2022-09-09 08:24:42 +01:00
act_ipt.c net/sched: act_ipt: add sanity checks on skb before calling target 2023-07-19 16:22:01 +02:00
act_meta_mark.c
act_meta_skbprio.c
act_meta_skbtcindex.c
act_mirred.c net/sched: act_mirred: Add carrier check 2023-05-17 11:53:34 +02:00
act_mpls.c net/sched: act_mpls: fix action bind logic 2023-03-11 13:55:28 +01:00
act_nat.c net: sched: act_nat: get rid of tcf_nat_walker and tcf_nat_search 2022-09-09 08:24:42 +01:00
act_pedit.c net/sched: act_pedit: Add size check for TCA_PEDIT_PARMS_EX 2023-07-19 16:22:05 +02:00
act_police.c net: sched: act_police: fix sparse errors in tcf_police_dump() 2023-06-14 11:15:21 +02:00
act_sample.c net/sched: act_sample: fix action bind logic 2023-03-11 13:55:28 +01:00
act_simple.c net: sched: act_simple: get rid of tcf_simp_walker and tcf_simp_search 2022-09-09 08:24:42 +01:00
act_skbedit.c net: sched: act_skbedit: get rid of tcf_skbedit_walker and tcf_skbedit_search 2022-09-09 08:24:42 +01:00
act_skbmod.c net: sched: act_skbmod: get rid of tcf_skbmod_walker and tcf_skbmod_search 2022-09-09 08:24:42 +01:00
act_tunnel_key.c net: sched: act_tunnel_key: get rid of tunnel_key_walker and tunnel_key_search 2022-09-09 08:24:42 +01:00
act_vlan.c net: sched: act_vlan: get rid of tcf_vlan_walker and tcf_vlan_search 2022-09-09 08:24:43 +01:00
cls_api.c net/sched: cls_api: Fix lockup on flushing explicitly created chain 2023-06-21 16:01:01 +02:00
cls_basic.c net: sched: use tc_cls_bind_class() in filter 2022-10-02 16:07:17 +01:00
cls_bpf.c net: sched: cls_bpf: Undo tcf_bind_filter in case of an error 2023-07-27 08:50:41 +02:00
cls_cgroup.c
cls_flow.c net/sched: use tc_cls_stats_dump() in filter 2022-09-20 15:54:13 -07:00
cls_flower.c net/sched: flower: Ensure both minimum and maximum ports are specified 2023-07-23 13:49:26 +02:00
cls_fw.c net/sched: cls_fw: No longer copy tcf_result on update to avoid use-after-free 2023-08-11 12:08:15 +02:00
cls_matchall.c net: sched: cls_matchall: Undo tcf_bind_filter in case of failure after mall_set_parms 2023-07-27 08:50:41 +02:00
cls_route.c net/sched: cls_route: No longer copy tcf_result on update to avoid use-after-free 2023-08-11 12:08:16 +02:00
cls_u32.c net: sched: cls_u32: Fix allocation size in u32_init() 2023-11-08 14:10:57 +01:00
em_canid.c
em_cmp.c
em_ipset.c
em_ipt.c
em_meta.c net: annotate data-races around sk->sk_lingertime 2023-09-13 09:42:33 +02:00
em_nbyte.c
em_text.c net: sched: em_text: fix possible memory leak in em_text_destroy() 2024-01-10 17:10:23 +01:00
em_u32.c
ematch.c net_sched: reject TCF_EM_SIMPLE case for complex ematch module 2022-12-31 13:32:55 +01:00
Kconfig net/sched: Retire rsvp classifier 2023-09-23 11:11:13 +02:00
Makefile net/sched: Retire rsvp classifier 2023-09-23 11:11:13 +02:00
sch_api.c net/sched: fix a qdisc modification with ambiguous command request 2023-08-30 16:11:03 +02:00
sch_atm.c net: sched: atm: dont intepret cls results when asked to drop 2023-01-12 12:02:24 +01:00
sch_blackhole.c
sch_cake.c Networking fixes for 6.1-rc2, including fixes from netfilter 2022-10-20 17:24:59 -07:00
sch_cbq.c net: sched: cbq: dont intepret cls results when asked to drop 2023-01-12 12:02:24 +01:00
sch_cbs.c net/sched: use tc_qdisc_stats_dump() in qdisc 2022-09-22 17:34:10 -07:00
sch_choke.c net: sched: choke: remove unused variables in struct choke_sched_data 2022-08-31 19:39:53 -07:00
sch_codel.c net: sched: remove redundant NULL check in change hook function 2022-09-01 08:06:45 +02:00
sch_drr.c net/sched: use tc_qdisc_stats_dump() in qdisc 2022-09-22 17:34:10 -07:00
sch_dsmark.c net/sched: use tc_qdisc_stats_dump() in qdisc 2022-09-22 17:34:10 -07:00
sch_etf.c net: sched: etf: remove true check in etf_enable_offload() 2022-09-01 20:08:32 -07:00
sch_ets.c net/sched: use tc_qdisc_stats_dump() in qdisc 2022-09-22 17:34:10 -07:00
sch_fifo.c net_sched: fix NULL deref in fifo_set_limit() 2021-10-01 14:59:10 -07:00
sch_fq.c net/sched: sch_fq: fix integer overflow of "credit" 2023-05-11 23:03:26 +09:00
sch_fq_codel.c Revert "net: sched: fq_codel: remove redundant resource cleanup in fq_codel_init()" 2022-10-19 13:47:09 +01:00
sch_fq_pie.c net/sched: fq_pie: avoid stalls in fq_pie_timer() 2023-09-19 12:28:00 +02:00
sch_frag.c Merge git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next 2021-12-31 14:35:40 +00:00
sch_generic.c net/sched: qdisc_destroy() old ingress and clsact Qdiscs before grafting 2023-06-21 16:01:01 +02:00
sch_gred.c net: sched: gred: prevent races when adding offloads to stats 2023-02-01 08:34:25 +01:00
sch_hfsc.c net/sched: sch_hfsc: upgrade 'rt' to 'sc' when it becomes a inner curve 2023-10-25 12:03:07 +02:00
sch_hhf.c net: sched: remove redundant NULL check in change hook function 2022-09-01 08:06:45 +02:00
sch_htb.c net: sched: sch: Fix off by one in htb_activate_prios() 2023-02-22 12:59:56 +01:00
sch_ingress.c net/sched: Reserve TC_H_INGRESS (TC_H_CLSACT) for ingress (clsact) Qdiscs 2023-06-09 10:34:03 +02:00
sch_mq.c net: sched: add rcu annotations around qdisc->qdisc_sleeping 2023-06-14 11:15:21 +02:00
sch_mqprio.c net/sched: mqprio: Add length check for TCA_MQPRIO_{MAX/MIN}_RATE64 2023-08-03 10:24:02 +02:00
sch_multiq.c net/sched: use tc_qdisc_stats_dump() in qdisc 2022-09-22 17:34:10 -07:00
sch_netem.c sch_netem: fix issues in netem_change() vs get_dist_table() 2023-08-16 18:27:31 +02:00
sch_pie.c net: sched: add rcu annotations around qdisc->qdisc_sleeping 2023-06-14 11:15:21 +02:00
sch_plug.c net: sched: sch_qfq: Fix UAF in qfq_dequeue() 2023-09-19 12:28:02 +02:00
sch_prio.c net/sched: use tc_qdisc_stats_dump() in qdisc 2022-09-22 17:34:10 -07:00
sch_qfq.c net: sched: sch_qfq: Fix UAF in qfq_dequeue() 2023-09-19 12:28:02 +02:00
sch_red.c net: sched: add rcu annotations around qdisc->qdisc_sleeping 2023-06-14 11:15:21 +02:00
sch_sfb.c Networking fixes for 6.1-rc2, including fixes from netfilter 2022-10-20 17:24:59 -07:00
sch_sfq.c net: sched: add rcu annotations around qdisc->qdisc_sleeping 2023-06-14 11:15:21 +02:00
sch_skbprio.c net/sched: use tc_qdisc_stats_dump() in qdisc 2022-09-22 17:34:10 -07:00
sch_taprio.c net/sched: taprio: Limit TCA_TAPRIO_ATTR_SCHED_CYCLE_TIME to INT_MAX. 2023-08-11 12:08:15 +02:00
sch_tbf.c net/sched: use tc_qdisc_stats_dump() in qdisc 2022-09-22 17:34:10 -07:00
sch_teql.c net: sched: add rcu annotations around qdisc->qdisc_sleeping 2023-06-14 11:15:21 +02:00