* [PATCH net] net/sched: act_ct: fix skb leak and crash on ooo frags
@ 2023-12-28 8:14 Tao Liu
2024-01-04 1:49 ` Jakub Kicinski
2024-01-05 16:20 ` patchwork-bot+netdevbpf
0 siblings, 2 replies; 5+ messages in thread
From: Tao Liu @ 2023-12-28 8:14 UTC (permalink / raw)
To: davem, kuba, edumazet, pabeni, vladbu, paulb
Cc: netdev, simon.horman, xiyou.wangcong, pablo, taoliu828
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: b57dc7c13ea9 ("net/sched: Introduce action ct")
Signed-off-by: Tao Liu <taoliu828@163.com>
---
net/sched/act_ct.c | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/net/sched/act_ct.c b/net/sched/act_ct.c
index f69c47945175..3d50215985d5 100644
--- a/net/sched/act_ct.c
+++ b/net/sched/act_ct.c
@@ -850,7 +850,6 @@ static int tcf_ct_handle_fragments(struct net *net, struct sk_buff *skb,
if (err || !frag)
return err;
- skb_get(skb);
err = nf_ct_handle_fragments(net, skb, zone, family, &proto, &mru);
if (err)
return err;
@@ -999,12 +998,8 @@ TC_INDIRECT_SCOPE int tcf_ct_act(struct sk_buff *skb, const struct tc_action *a,
nh_ofs = skb_network_offset(skb);
skb_pull_rcsum(skb, nh_ofs);
err = tcf_ct_handle_fragments(net, skb, family, p->zone, &defrag);
- if (err == -EINPROGRESS) {
- retval = TC_ACT_STOLEN;
- goto out_clear;
- }
if (err)
- goto drop;
+ goto out_frag;
err = nf_ct_skb_network_trim(skb, family);
if (err)
@@ -1091,6 +1086,11 @@ TC_INDIRECT_SCOPE int tcf_ct_act(struct sk_buff *skb, const struct tc_action *a,
qdisc_skb_cb(skb)->pkt_len = skb->len;
return retval;
+out_frag:
+ if (err != -EINPROGRESS)
+ tcf_action_inc_drop_qstats(&c->common);
+ return TC_ACT_CONSUMED;
+
drop:
tcf_action_inc_drop_qstats(&c->common);
return TC_ACT_SHOT;
--
2.31.1
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH net] net/sched: act_ct: fix skb leak and crash on ooo frags
2023-12-28 8:14 [PATCH net] net/sched: act_ct: fix skb leak and crash on ooo frags Tao Liu
@ 2024-01-04 1:49 ` Jakub Kicinski
2024-01-04 16:48 ` Xin Long
2024-01-08 8:12 ` Vlad Buslov
2024-01-05 16:20 ` patchwork-bot+netdevbpf
1 sibling, 2 replies; 5+ messages in thread
From: Jakub Kicinski @ 2024-01-04 1:49 UTC (permalink / raw)
To: vladbu, Xin Long
Cc: Tao Liu, davem, edumazet, pabeni, paulb, netdev, simon.horman,
xiyou.wangcong, pablo
On Thu, 28 Dec 2023 16:14:57 +0800 Tao Liu wrote:
> 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.
Vlad, Xin Long, does this look good to you?
--
pw-bot: needs-ack
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH net] net/sched: act_ct: fix skb leak and crash on ooo frags
2024-01-04 1:49 ` Jakub Kicinski
@ 2024-01-04 16:48 ` Xin Long
2024-01-08 8:12 ` Vlad Buslov
1 sibling, 0 replies; 5+ messages in thread
From: Xin Long @ 2024-01-04 16:48 UTC (permalink / raw)
To: Jakub Kicinski
Cc: vladbu, Tao Liu, davem, edumazet, pabeni, paulb, netdev,
simon.horman, xiyou.wangcong, pablo
On Wed, Jan 3, 2024 at 8:49 PM Jakub Kicinski <kuba@kernel.org> wrote:
>
> On Thu, 28 Dec 2023 16:14:57 +0800 Tao Liu wrote:
> > 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.
>
> Vlad, Xin Long, does this look good to you?
Looks good to me.
It seems that skb_get() must be avoided to use before ip defrag,
and also I see no reason to keep the skb if defrag fails in tcf_ct_act().
nf_ct_handle_fragments() is also called in ovs_ct_handle_fragments()
where it doesn't hold the skb.
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH net] net/sched: act_ct: fix skb leak and crash on ooo frags
2023-12-28 8:14 [PATCH net] net/sched: act_ct: fix skb leak and crash on ooo frags Tao Liu
2024-01-04 1:49 ` Jakub Kicinski
@ 2024-01-05 16:20 ` patchwork-bot+netdevbpf
1 sibling, 0 replies; 5+ messages in thread
From: patchwork-bot+netdevbpf @ 2024-01-05 16:20 UTC (permalink / raw)
To: Tao Liu
Cc: davem, kuba, edumazet, pabeni, vladbu, paulb, netdev,
simon.horman, xiyou.wangcong, pablo
Hello:
This patch was applied to netdev/net.git (main)
by Jakub Kicinski <kuba@kernel.org>:
On Thu, 28 Dec 2023 16:14:57 +0800 you wrote:
> 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.
>
> [...]
Here is the summary with links:
- [net] net/sched: act_ct: fix skb leak and crash on ooo frags
https://git.kernel.org/netdev/net/c/3f14b377d01d
You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH net] net/sched: act_ct: fix skb leak and crash on ooo frags
2024-01-04 1:49 ` Jakub Kicinski
2024-01-04 16:48 ` Xin Long
@ 2024-01-08 8:12 ` Vlad Buslov
1 sibling, 0 replies; 5+ messages in thread
From: Vlad Buslov @ 2024-01-08 8:12 UTC (permalink / raw)
To: Jakub Kicinski
Cc: Xin Long, Tao Liu, davem, edumazet, pabeni, paulb, netdev,
simon.horman, xiyou.wangcong, pablo
On Wed 03 Jan 2024 at 17:49, Jakub Kicinski <kuba@kernel.org> wrote:
> On Thu, 28 Dec 2023 16:14:57 +0800 Tao Liu wrote:
>> 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.
>
> Vlad, Xin Long, does this look good to you?
Hi, sorry for the late response. LGTM, will report tomorrow if this
triggers anything in our regression runs.
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2024-01-08 8:14 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-12-28 8:14 [PATCH net] net/sched: act_ct: fix skb leak and crash on ooo frags Tao Liu
2024-01-04 1:49 ` Jakub Kicinski
2024-01-04 16:48 ` Xin Long
2024-01-08 8:12 ` Vlad Buslov
2024-01-05 16:20 ` patchwork-bot+netdevbpf
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).