In the Linux kernel, the following vulnerability has been resolved:
netfilter: brnetfilter: do not check confirmed bit in brnflocalin() after confirm
When send a broadcast packet to a tap device, which was added to a bridge, brnflocal_in() is called to confirm the conntrack. If another conntrack with the same hash value is added to the hash table, which can be triggered by a normal packet to a non-bridge device, the below warning may happen.
------------[ cut here ]------------ WARNING: CPU: 1 PID: 96 at net/bridge/brnetfilterhooks.c:632 brnflocalin+0x168/0x200 CPU: 1 UID: 0 PID: 96 Comm: tapsend Not tainted 6.17.0-rc2-dirty #44 PREEMPT(voluntary) RIP: 0010:brnflocalin+0x168/0x200 Call Trace: <TASK> nfhookslow+0x3e/0xf0 brpassframeup+0x103/0x180 brhandleframefinish+0x2de/0x5b0 brnfhookthresh+0xc0/0x120 brnfpreroutingfinish+0x168/0x3a0 brnfprerouting+0x237/0x5e0 brhandleframe+0x1ec/0x3c0 _netifreceiveskbcore+0x225/0x1210 _netifreceiveskbonecore+0x37/0xa0 netifreceiveskb+0x36/0x160 tungetuser+0xa54/0x10c0 tunchrwriteiter+0x65/0xb0 vfswrite+0x305/0x410 ksyswrite+0x60/0xd0 dosyscall64+0xa4/0x260 entrySYSCALL64after_hwframe+0x77/0x7f </TASK> ---[ end trace 0000000000000000 ]---
To solve the hash conflict, nfctresolveclash() try to merge the conntracks, and update skb->nfct. However, brnflocal_in() still use the old ct from local variable 'nfct' after confirm(), which leads to this warning.
If confirm() does not insert the conntrack entry and return NFDROP, the warning may also occur. There is no need to reserve the WARNON_ONCE, just remove it.