WARNING in nf_flow_offload_gc_step

Status: upstream: reported C repro on 2026/10/31 16:51
Subsystems: netfilter
Labels: prio:high
[Documentation on labels]
Reported-by: syzbot+e1a88d8b7e4cf6b51d85@syzkaller.appspotmail.com
First crash: 4d00h, last: 3d23h
✨ AI-generated root cause summary:

In the Netfilter flowtable subsystem, nf_flow_table_extend_ct_timeout() only accounts for IPPROTO_UDP and IPPROTO_TCP when refreshing conntrack timeouts during garbage collection. However, both tc act_ct and nftables flow offload support offloading IPPROTO_GRE connections to the flowtable. When the garbage collector checks an offloaded GRE connection whose timeout has dropped below min_timeout, the missing case in nf_flow_table_extend_ct_timeout() triggers the default: WARN_ON_ONCE(1) branch. In a production kernel without panic_on_warn, the warning does not crash the system and no memory corruption occurs.

▶ ▼ ✨ Full AI root cause analysis
Based on kernel commit d135ab453a74:

Root Cause Analysis

1. Functions, Structs, and Files Involved


2. Triggering Mechanism and Violated Invariants

  1. Both tc's act_ct module (net/sched/act_ct.c) and nftables' flow offload expression (net/netfilter/nft_flow_offload.c) support offloading IPPROTO_GRE (protocol number 47 / 0x2f) flows into the Netfilter flowtable when CONFIG_NF_CT_PROTO_GRE is enabled, setting the IPS_OFFLOAD_BIT on the connection struct nf_conn.
  2. When GRE traffic flows, connection tracking sets standard timeouts for GRE (e.g., ct->proto.gre.timeout = 30*HZ or ct->proto.gre.stream_timeout = 180*HZ in nf_conntrack_gre_packet()). In particular, datapath packet processing or initial creation leaves ct->timeout - nfct_time_stamp well below min_timeout = NF_CT_DAY / 2 (12 hours).
  3. Periodically, the flowtable garbage collection workqueue thread (nf_flow_offload_work_gc -> nf_flow_table_gc_run -> nf_flow_table_iterate -> nf_flow_offload_gc_step) inspects active offload entries and calls nf_flow_table_extend_ct_timeout(flow->ct) to keep the underlying conntrack entry from expiring while it is offloaded.
  4. In nf_flow_table_extend_ct_timeout(), the logic checks the L4 protocol number of the connection:
    u8 l4proto = nf_ct_protonum(ct);
    u32 new_timeout = 1;
    
    switch (l4proto) {
    case IPPROTO_UDP:
        new_timeout = NF_CT_DAY;
        break;
    case IPPROTO_TCP:
        new_timeout = nf_flow_table_tcp_timeout(ct);
        break;
    default:
        WARN_ON_ONCE(1);
        break;
    }
    
  5. Because l4proto is IPPROTO_GRE (47 / 0x2f, recorded in R14 in the crash dump), the switch statement has no case matching IPPROTO_GRE. It falls into the default: branch, firing WARN_ON_ONCE(1) at line 553.

3. Runtime Consequences in Production Kernel

  • Memory Corruption (false): No out-of-bounds access, invalid free, use-after-free, or corrupted pointers occur. Refcounts on ct (ct->ct_general.use) are balanced with nf_ct_put(ct).
  • Denial of Service (false): In a production kernel without panic_on_warn, WARN_ON_ONCE prints a kernel warning once and allows execution to continue. After hitting the warning, new_timeout (initialized to 1) is applied via cmpxchg(&ct->timeout, ct_timeout, new_timeout + nfct_time_stamp). This causes the conntrack entry's timeout to expire in 1 jiffy, causing conntrack cleanup routines to reclaim the entry earlier than desired. However, this is handled gracefully through standard conntrack and flowtable expiration logic without crashing, hanging, or leaking kernel resources.
  • Information Leak (none): No kernel memory or pointer values are leaked to userspace or network interfaces.
  • Subsystem Classification:
    • IsNetCandidate = true: The issue is entirely within networking (net/netfilter flow table and conntrack subsystems).
    • IsKVMCandidate = false: Virtualization/KVM is not involved.
▶ ▼ ✨ AI Jobs (1)
ID Workflow Result Correct Bug Created Started Finished Revision
2d1bf3ae assessment-security DenialOfService: ❌ Exploitable: ❌ FilesystemTrigger: ❌ FuzzingArtifact: ❌ MemoryCorruption: ❌ NetworkNeedsSetup: ✅ NetworkTrigger: ✅ PeripheralTrigger: ❌ RemoteTrigger: ❌ Unprivileged: ❌ UserNamespace: ✅ VMGuestTrigger: ❌ VMHostTrigger: ❌ ❓ WARNING in nf_flow_offload_gc_step 2026/10/28 02:33 2026/10/28 02:33 2026/10/28 03:26 96923c60
▶ ▼ Discussions (1)
Title Replies (including bot) Last reply
[syzbot] [netfilter?] WARNING in nf_flow_offload_gc_step 0 (1) 2026/10/31 16:51

Sample crash report:
------------[ cut here ]------------
1
WARNING: net/netfilter/nf_flow_table_core.c:553 at nf_flow_table_extend_ct_timeout net/netfilter/nf_flow_table_core.c:553 [inline], CPU#2: kworker/2:2/1358
WARNING: net/netfilter/nf_flow_table_core.c:553 at nf_flow_offload_gc_step+0xd84/0xf60 net/netfilter/nf_flow_table_core.c:593, CPU#2: kworker/2:2/1358
Modules linked in:
CPU: 2 UID: 0 PID: 1358 Comm: kworker/2:2 Not tainted syzkaller #0 PREEMPT(full) 
Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.3-debian-1.16.3-2 04/01/2014
Workqueue: events_power_efficient nf_flow_offload_work_gc
RIP: 0010:nf_flow_table_extend_ct_timeout net/netfilter/nf_flow_table_core.c:553 [inline]
RIP: 0010:nf_flow_offload_gc_step+0xd84/0xf60 net/netfilter/nf_flow_table_core.c:593
Code: f8 e9 82 fd ff ff 4c 89 f7 e8 28 e1 6a f8 e9 12 fc ff ff 48 c7 c7 80 f2 c0 8f e8 17 e1 6a f8 e9 ae fc ff ff e8 1d cb f1 f7 90 <0f> 0b 90 41 be 01 00 00 00 e9 7d fc ff ff e8 09 cb f1 f7 48 8b 04
RSP: 0018:ffffc9000618fa88 EFLAGS: 00010293
RAX: 0000000000000000 RBX: ffff88803e161380 RCX: 0000000000000000
RDX: ffff88802c392580 RSI: ffffffff8a1c51f3 RDI: ffff88802c392580
RBP: ffff88803e161488 R08: 0000000000000001 R09: 0000000000000011
R10: 000000000000002f R11: 0000000000000000 R12: 1ffff92000c31f56
R13: ffff88803818f868 R14: 000000000000002f R15: ffffffff8fc0f280
FS:  0000000000000000(0000) GS:ffff8880d469c000(0000) knlGS:0000000000000000
CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 0000200000012000 CR3: 000000002f277000 CR4: 0000000000352ef0
Call Trace:
 <TASK>
 nf_flow_table_iterate net/netfilter/nf_flow_table_core.c:459 [inline]
 nf_flow_table_gc_run net/netfilter/nf_flow_table_core.c:616 [inline]
 nf_flow_offload_work_gc+0x11e/0x1e0 net/netfilter/nf_flow_table_core.c:624
 process_one_work+0xac7/0x1b10 kernel/workqueue.c:3495
 process_scheduled_works kernel/workqueue.c:3578 [inline]
 worker_thread+0x5ef/0xe50 kernel/workqueue.c:3659
 kthread+0x373/0x450 kernel/kthread.c:436
 ret_from_fork+0x730/0xd60 arch/x86/kernel/process.c:158
 ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:245
 </TASK>

Crashes (3):
Time Kernel Commit Syzkaller Config Log Report Syz repro C repro VM info Assets (help?) Manager Title
2026/10/27 17:40 upstream d135ab453a74 96923c60 .config console log report syz / log C [disk image (non-bootable)] [vmlinux] [kernel image] ci-qemu-upstream WARNING in nf_flow_offload_gc_step
2026/10/27 17:14 upstream d135ab453a74 96923c60 .config console log report syz / log C [disk image (non-bootable)] [vmlinux] [kernel image] ci-qemu-upstream WARNING in nf_flow_offload_gc_step
2026/10/27 16:47 upstream d135ab453a74 96923c60 .config console log report info [disk image (non-bootable)] [vmlinux] [kernel image] ci-qemu-upstream WARNING in nf_flow_offload_gc_step
* Struck through repros no longer work on HEAD.