<feed xmlns='http://www.w3.org/2005/Atom'>
<title>linux/net, branch v6.16</title>
<subtitle>Mirror of https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/
</subtitle>
<id>https://git.shady.money/linux/atom?h=v6.16</id>
<link rel='self' href='https://git.shady.money/linux/atom?h=v6.16'/>
<link rel='alternate' type='text/html' href='https://git.shady.money/linux/'/>
<updated>2025-07-24T10:30:40Z</updated>
<entry>
<title>Merge tag 'ipsec-2025-07-23' of git://git.kernel.org/pub/scm/linux/kernel/git/klassert/ipsec</title>
<updated>2025-07-24T10:30:40Z</updated>
<author>
<name>Paolo Abeni</name>
<email>pabeni@redhat.com</email>
</author>
<published>2025-07-24T10:30:39Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/linux/commit/?id=291d5dc80eca1fc67a0fa4c861d13c101345501a'/>
<id>urn:sha1:291d5dc80eca1fc67a0fa4c861d13c101345501a</id>
<content type='text'>
Steffen Klassert says:

====================
pull request (net): ipsec 2025-07-23

1) Premption fixes for xfrm_state_find.
   From Sabrina Dubroca.

2) Initialize offload path also for SW IPsec GRO. This fixes a
   performance regression on SW IPsec offload.
   From Leon Romanovsky.

3) Fix IPsec UDP GRO for IKE packets.
   From Tobias Brunner,

4) Fix transport header setting for IPcomp after decompressing.
   From Fernando Fernandez Mancera.

5)  Fix use-after-free when xfrmi_changelink tries to change
    collect_md for a xfrm interface.
    From Eyal Birger .

6) Delete the special IPcomp x-&gt;tunnel state along with the state x
   to avoid refcount problems.
   From Sabrina Dubroca.

Please pull or let me know if there are problems.

* tag 'ipsec-2025-07-23' of git://git.kernel.org/pub/scm/linux/kernel/git/klassert/ipsec:
  Revert "xfrm: destroy xfrm_state synchronously on net exit path"
  xfrm: delete x-&gt;tunnel as we delete x
  xfrm: interface: fix use-after-free after changing collect_md xfrm interface
  xfrm: ipcomp: adjust transport header after decompressing
  xfrm: Set transport header to fix UDP GRO handling
  xfrm: always initialize offload path
  xfrm: state: use a consistent pcpu_id in xfrm_state_find
  xfrm: state: initialize state_ptrs earlier in xfrm_state_find
====================

Link: https://patch.msgid.link/20250723075417.3432644-1-steffen.klassert@secunet.com
Signed-off-by: Paolo Abeni &lt;pabeni@redhat.com&gt;
</content>
</entry>
<entry>
<title>net/sched: sch_qfq: Avoid triggering might_sleep in atomic context in qfq_delete_class</title>
<updated>2025-07-22T09:48:34Z</updated>
<author>
<name>Xiang Mei</name>
<email>xmei5@asu.edu</email>
</author>
<published>2025-07-17T23:01:28Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/linux/commit/?id=cf074eca0065bc5142e6004ae236bb35a2687fdf'/>
<id>urn:sha1:cf074eca0065bc5142e6004ae236bb35a2687fdf</id>
<content type='text'>
might_sleep could be trigger in the atomic context in qfq_delete_class.

qfq_destroy_class was moved into atomic context locked
by sch_tree_lock to avoid a race condition bug on
qfq_aggregate. However, might_sleep could be triggered by
qfq_destroy_class, which introduced sleeping in atomic context (path:
qfq_destroy_class-&gt;qdisc_put-&gt;__qdisc_destroy-&gt;lockdep_unregister_key
-&gt;might_sleep).

Considering the race is on the qfq_aggregate objects, keeping
qfq_rm_from_agg in the lock but moving the left part out can solve
this issue.

Fixes: 5e28d5a3f774 ("net/sched: sch_qfq: Fix race condition on qfq_aggregate")
Reported-by: Dan Carpenter &lt;dan.carpenter@linaro.org&gt;
Signed-off-by: Xiang Mei &lt;xmei5@asu.edu&gt;
Link: https://patch.msgid.link/4a04e0cc-a64b-44e7-9213-2880ed641d77@sabinyo.mountain
Reviewed-by: Cong Wang &lt;xiyou.wangcong@gmail.com&gt;
Reviewed-by: Dan Carpenter &lt;dan.carpenter@linaro.org&gt;
Link: https://patch.msgid.link/20250717230128.159766-1-xmei5@asu.edu
Signed-off-by: Paolo Abeni &lt;pabeni@redhat.com&gt;

</content>
</entry>
<entry>
<title>net: appletalk: Fix use-after-free in AARP proxy probe</title>
<updated>2025-07-21T23:55:08Z</updated>
<author>
<name>Kito Xu (veritas501)</name>
<email>hxzene@gmail.com</email>
</author>
<published>2025-07-17T01:28:43Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/linux/commit/?id=6c4a92d07b0850342d3becf2e608f805e972467c'/>
<id>urn:sha1:6c4a92d07b0850342d3becf2e608f805e972467c</id>
<content type='text'>
The AARP proxy‐probe routine (aarp_proxy_probe_network) sends a probe,
releases the aarp_lock, sleeps, then re-acquires the lock.  During that
window an expire timer thread (__aarp_expire_timer) can remove and
kfree() the same entry, leading to a use-after-free.

race condition:

         cpu 0                          |            cpu 1
    atalk_sendmsg()                     |   atif_proxy_probe_device()
    aarp_send_ddp()                     |   aarp_proxy_probe_network()
    mod_timer()                         |   lock(aarp_lock) // LOCK!!
    timeout around 200ms                |   alloc(aarp_entry)
    and then call                       |   proxies[hash] = aarp_entry
    aarp_expire_timeout()               |   aarp_send_probe()
                                        |   unlock(aarp_lock) // UNLOCK!!
    lock(aarp_lock) // LOCK!!           |   msleep(100);
    __aarp_expire_timer(&amp;proxies[ct])   |
    free(aarp_entry)                    |
    unlock(aarp_lock) // UNLOCK!!       |
                                        |   lock(aarp_lock) // LOCK!!
                                        |   UAF aarp_entry !!

==================================================================
BUG: KASAN: slab-use-after-free in aarp_proxy_probe_network+0x560/0x630 net/appletalk/aarp.c:493
Read of size 4 at addr ffff8880123aa360 by task repro/13278

CPU: 3 UID: 0 PID: 13278 Comm: repro Not tainted 6.15.2 #3 PREEMPT(full)
Call Trace:
 &lt;TASK&gt;
 __dump_stack lib/dump_stack.c:94 [inline]
 dump_stack_lvl+0x116/0x1b0 lib/dump_stack.c:120
 print_address_description mm/kasan/report.c:408 [inline]
 print_report+0xc1/0x630 mm/kasan/report.c:521
 kasan_report+0xca/0x100 mm/kasan/report.c:634
 aarp_proxy_probe_network+0x560/0x630 net/appletalk/aarp.c:493
 atif_proxy_probe_device net/appletalk/ddp.c:332 [inline]
 atif_ioctl+0xb58/0x16c0 net/appletalk/ddp.c:857
 atalk_ioctl+0x198/0x2f0 net/appletalk/ddp.c:1818
 sock_do_ioctl+0xdc/0x260 net/socket.c:1190
 sock_ioctl+0x239/0x6a0 net/socket.c:1311
 vfs_ioctl fs/ioctl.c:51 [inline]
 __do_sys_ioctl fs/ioctl.c:906 [inline]
 __se_sys_ioctl fs/ioctl.c:892 [inline]
 __x64_sys_ioctl+0x194/0x200 fs/ioctl.c:892
 do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
 do_syscall_64+0xcb/0x250 arch/x86/entry/syscall_64.c:94
 entry_SYSCALL_64_after_hwframe+0x77/0x7f
 &lt;/TASK&gt;

Allocated:
 aarp_alloc net/appletalk/aarp.c:382 [inline]
 aarp_proxy_probe_network+0xd8/0x630 net/appletalk/aarp.c:468
 atif_proxy_probe_device net/appletalk/ddp.c:332 [inline]
 atif_ioctl+0xb58/0x16c0 net/appletalk/ddp.c:857
 atalk_ioctl+0x198/0x2f0 net/appletalk/ddp.c:1818

Freed:
 kfree+0x148/0x4d0 mm/slub.c:4841
 __aarp_expire net/appletalk/aarp.c:90 [inline]
 __aarp_expire_timer net/appletalk/aarp.c:261 [inline]
 aarp_expire_timeout+0x480/0x6e0 net/appletalk/aarp.c:317

The buggy address belongs to the object at ffff8880123aa300
 which belongs to the cache kmalloc-192 of size 192
The buggy address is located 96 bytes inside of
 freed 192-byte region [ffff8880123aa300, ffff8880123aa3c0)

Memory state around the buggy address:
 ffff8880123aa200: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 ffff8880123aa280: 00 00 00 00 fc fc fc fc fc fc fc fc fc fc fc fc
&gt;ffff8880123aa300: fa fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
                                                       ^
 ffff8880123aa380: fb fb fb fb fb fb fb fb fc fc fc fc fc fc fc fc
 ffff8880123aa400: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
==================================================================

Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Signed-off-by: Kito Xu (veritas501) &lt;hxzene@gmail.com&gt;
Link: https://patch.msgid.link/20250717012843.880423-1-hxzene@gmail.com
Signed-off-by: Jakub Kicinski &lt;kuba@kernel.org&gt;
</content>
</entry>
<entry>
<title>Merge tag 'for-net-2025-07-17' of git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth</title>
<updated>2025-07-17T14:54:49Z</updated>
<author>
<name>Jakub Kicinski</name>
<email>kuba@kernel.org</email>
</author>
<published>2025-07-17T14:54:48Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/linux/commit/?id=a2bbaff6816a1531fd61b07739c3f2a500cd3693'/>
<id>urn:sha1:a2bbaff6816a1531fd61b07739c3f2a500cd3693</id>
<content type='text'>
Luiz Augusto von Dentz says:

====================
bluetooth pull request for net:

 - hci_sync: fix connectable extended advertising when using static random address
 - hci_core: fix typos in macros
 - hci_core: add missing braces when using macro parameters
 - hci_core: replace 'quirks' integer by 'quirk_flags' bitmap
 - SMP: If an unallowed command is received consider it a failure
 - SMP: Fix using HCI_ERROR_REMOTE_USER_TERM on timeout
 - L2CAP: Fix null-ptr-deref in l2cap_sock_resume_cb()
 - L2CAP: Fix attempting to adjust outgoing MTU
 - btintel: Check if controller is ISO capable on btintel_classify_pkt_type
 - btusb: QCA: Fix downloading wrong NVM for WCN6855 GF variant without board ID

* tag 'for-net-2025-07-17' of git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth:
  Bluetooth: L2CAP: Fix attempting to adjust outgoing MTU
  Bluetooth: btusb: QCA: Fix downloading wrong NVM for WCN6855 GF variant without board ID
  Bluetooth: hci_dev: replace 'quirks' integer by 'quirk_flags' bitmap
  Bluetooth: hci_core: add missing braces when using macro parameters
  Bluetooth: hci_core: fix typos in macros
  Bluetooth: SMP: Fix using HCI_ERROR_REMOTE_USER_TERM on timeout
  Bluetooth: SMP: If an unallowed command is received consider it a failure
  Bluetooth: btintel: Check if controller is ISO capable on btintel_classify_pkt_type
  Bluetooth: hci_sync: fix connectable extended advertising when using static random address
  Bluetooth: Fix null-ptr-deref in l2cap_sock_resume_cb()
====================

Link: https://patch.msgid.link/20250717142849.537425-1-luiz.dentz@gmail.com
Signed-off-by: Jakub Kicinski &lt;kuba@kernel.org&gt;
</content>
</entry>
<entry>
<title>rxrpc: Fix to use conn aborts for conn-wide failures</title>
<updated>2025-07-17T14:50:48Z</updated>
<author>
<name>David Howells</name>
<email>dhowells@redhat.com</email>
</author>
<published>2025-07-17T07:43:45Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/linux/commit/?id=f0295678ad304195927829b1dbf06553aa2187b0'/>
<id>urn:sha1:f0295678ad304195927829b1dbf06553aa2187b0</id>
<content type='text'>
Fix rxrpc to use connection-level aborts for things that affect the whole
connection, such as the service ID not matching a local service.

Fixes: 57af281e5389 ("rxrpc: Tidy up abort generation infrastructure")
Reported-by: Jeffrey Altman &lt;jaltman@auristor.com&gt;
Signed-off-by: David Howells &lt;dhowells@redhat.com&gt;
Reviewed-by: Jeffrey Altman &lt;jaltman@auristor.com&gt;
cc: Marc Dionne &lt;marc.dionne@auristor.com&gt;
cc: Simon Horman &lt;horms@kernel.org&gt;
cc: linux-afs@lists.infradead.org
Link: https://patch.msgid.link/20250717074350.3767366-6-dhowells@redhat.com
Signed-off-by: Jakub Kicinski &lt;kuba@kernel.org&gt;
</content>
</entry>
<entry>
<title>rxrpc: Fix transmission of an abort in response to an abort</title>
<updated>2025-07-17T14:50:48Z</updated>
<author>
<name>David Howells</name>
<email>dhowells@redhat.com</email>
</author>
<published>2025-07-17T07:43:44Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/linux/commit/?id=e9c0b96ec0a34fcacdf9365713578d83cecac34c'/>
<id>urn:sha1:e9c0b96ec0a34fcacdf9365713578d83cecac34c</id>
<content type='text'>
Under some circumstances, such as when a server socket is closing, ABORT
packets will be generated in response to incoming packets.  Unfortunately,
this also may include generating aborts in response to incoming aborts -
which may cause a cycle.  It appears this may be made possible by giving
the client a multicast address.

Fix this such that rxrpc_reject_packet() will refuse to generate aborts in
response to aborts.

Fixes: 248f219cb8bc ("rxrpc: Rewrite the data and ack handling code")
Signed-off-by: David Howells &lt;dhowells@redhat.com&gt;
Reviewed-by: Jeffrey Altman &lt;jaltman@auristor.com&gt;
cc: Marc Dionne &lt;marc.dionne@auristor.com&gt;
cc: Junvyyang, Tencent Zhuque Lab &lt;zhuque@tencent.com&gt;
cc: LePremierHomme &lt;kwqcheii@proton.me&gt;
cc: Linus Torvalds &lt;torvalds@linux-foundation.org&gt;
cc: Simon Horman &lt;horms@kernel.org&gt;
cc: linux-afs@lists.infradead.org
Link: https://patch.msgid.link/20250717074350.3767366-5-dhowells@redhat.com
Signed-off-by: Jakub Kicinski &lt;kuba@kernel.org&gt;
</content>
</entry>
<entry>
<title>rxrpc: Fix notification vs call-release vs recvmsg</title>
<updated>2025-07-17T14:50:48Z</updated>
<author>
<name>David Howells</name>
<email>dhowells@redhat.com</email>
</author>
<published>2025-07-17T07:43:43Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/linux/commit/?id=2fd895842d49c23137ae48252dd211e5d6d8a3ed'/>
<id>urn:sha1:2fd895842d49c23137ae48252dd211e5d6d8a3ed</id>
<content type='text'>
When a call is released, rxrpc takes the spinlock and removes it from
-&gt;recvmsg_q in an effort to prevent racing recvmsg() invocations from
seeing the same call.  Now, rxrpc_recvmsg() only takes the spinlock when
actually removing a call from the queue; it doesn't, however, take it in
the lead up to that when it checks to see if the queue is empty.  It *does*
hold the socket lock, which prevents a recvmsg/recvmsg race - but this
doesn't prevent sendmsg from ending the call because sendmsg() drops the
socket lock and relies on the call-&gt;user_mutex.

Fix this by firstly removing the bit in rxrpc_release_call() that dequeues
the released call and, instead, rely on recvmsg() to simply discard
released calls (done in a preceding fix).

Secondly, rxrpc_notify_socket() is abandoned if the call is already marked
as released rather than trying to be clever by setting both pointers in
call-&gt;recvmsg_link to NULL to trick list_empty().  This isn't perfect and
can still race, resulting in a released call on the queue, but recvmsg()
will now clean that up.

Fixes: 17926a79320a ("[AF_RXRPC]: Provide secure RxRPC sockets for use by userspace and kernel both")
Signed-off-by: David Howells &lt;dhowells@redhat.com&gt;
Reviewed-by: Jeffrey Altman &lt;jaltman@auristor.com&gt;
cc: Marc Dionne &lt;marc.dionne@auristor.com&gt;
cc: Junvyyang, Tencent Zhuque Lab &lt;zhuque@tencent.com&gt;
cc: LePremierHomme &lt;kwqcheii@proton.me&gt;
cc: Simon Horman &lt;horms@kernel.org&gt;
cc: linux-afs@lists.infradead.org
Link: https://patch.msgid.link/20250717074350.3767366-4-dhowells@redhat.com
Signed-off-by: Jakub Kicinski &lt;kuba@kernel.org&gt;
</content>
</entry>
<entry>
<title>rxrpc: Fix recv-recv race of completed call</title>
<updated>2025-07-17T14:50:48Z</updated>
<author>
<name>David Howells</name>
<email>dhowells@redhat.com</email>
</author>
<published>2025-07-17T07:43:42Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/linux/commit/?id=962fb1f651c2cf2083e0c3ef53ba69e3b96d3fbc'/>
<id>urn:sha1:962fb1f651c2cf2083e0c3ef53ba69e3b96d3fbc</id>
<content type='text'>
If a call receives an event (such as incoming data), the call gets placed
on the socket's queue and a thread in recvmsg can be awakened to go and
process it.  Once the thread has picked up the call off of the queue,
further events will cause it to be requeued, and once the socket lock is
dropped (recvmsg uses call-&gt;user_mutex to allow the socket to be used in
parallel), a second thread can come in and its recvmsg can pop the call off
the socket queue again.

In such a case, the first thread will be receiving stuff from the call and
the second thread will be blocked on call-&gt;user_mutex.  The first thread
can, at this point, process both the event that it picked call for and the
event that the second thread picked the call for and may see the call
terminate - in which case the call will be "released", decoupling the call
from the user call ID assigned to it (RXRPC_USER_CALL_ID in the control
message).

The first thread will return okay, but then the second thread will wake up
holding the user_mutex and, if it sees that the call has been released by
the first thread, it will BUG thusly:

	kernel BUG at net/rxrpc/recvmsg.c:474!

Fix this by just dequeuing the call and ignoring it if it is seen to be
already released.  We can't tell userspace about it anyway as the user call
ID has become stale.

Fixes: 248f219cb8bc ("rxrpc: Rewrite the data and ack handling code")
Reported-by: Junvyyang, Tencent Zhuque Lab &lt;zhuque@tencent.com&gt;
Signed-off-by: David Howells &lt;dhowells@redhat.com&gt;
Reviewed-by: Jeffrey Altman &lt;jaltman@auristor.com&gt;
cc: LePremierHomme &lt;kwqcheii@proton.me&gt;
cc: Marc Dionne &lt;marc.dionne@auristor.com&gt;
cc: Simon Horman &lt;horms@kernel.org&gt;
cc: linux-afs@lists.infradead.org
Link: https://patch.msgid.link/20250717074350.3767366-3-dhowells@redhat.com
Signed-off-by: Jakub Kicinski &lt;kuba@kernel.org&gt;
</content>
</entry>
<entry>
<title>rxrpc: Fix irq-disabled in local_bh_enable()</title>
<updated>2025-07-17T14:50:48Z</updated>
<author>
<name>David Howells</name>
<email>dhowells@redhat.com</email>
</author>
<published>2025-07-17T07:43:41Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/linux/commit/?id=e4d2878369d590bf8455e3678a644e503172eafa'/>
<id>urn:sha1:e4d2878369d590bf8455e3678a644e503172eafa</id>
<content type='text'>
The rxrpc_assess_MTU_size() function calls down into the IP layer to find
out the MTU size for a route.  When accepting an incoming call, this is
called from rxrpc_new_incoming_call() which holds interrupts disabled
across the code that calls down to it.  Unfortunately, the IP layer uses
local_bh_enable() which, config dependent, throws a warning if IRQs are
enabled:

WARNING: CPU: 1 PID: 5544 at kernel/softirq.c:387 __local_bh_enable_ip+0x43/0xd0
...
RIP: 0010:__local_bh_enable_ip+0x43/0xd0
...
Call Trace:
 &lt;TASK&gt;
 rt_cache_route+0x7e/0xa0
 rt_set_nexthop.isra.0+0x3b3/0x3f0
 __mkroute_output+0x43a/0x460
 ip_route_output_key_hash+0xf7/0x140
 ip_route_output_flow+0x1b/0x90
 rxrpc_assess_MTU_size.isra.0+0x2a0/0x590
 rxrpc_new_incoming_peer+0x46/0x120
 rxrpc_alloc_incoming_call+0x1b1/0x400
 rxrpc_new_incoming_call+0x1da/0x5e0
 rxrpc_input_packet+0x827/0x900
 rxrpc_io_thread+0x403/0xb60
 kthread+0x2f7/0x310
 ret_from_fork+0x2a/0x230
 ret_from_fork_asm+0x1a/0x30
...
hardirqs last  enabled at (23): _raw_spin_unlock_irq+0x24/0x50
hardirqs last disabled at (24): _raw_read_lock_irq+0x17/0x70
softirqs last  enabled at (0): copy_process+0xc61/0x2730
softirqs last disabled at (25): rt_add_uncached_list+0x3c/0x90

Fix this by moving the call to rxrpc_assess_MTU_size() out of
rxrpc_init_peer() and further up the stack where it can be done without
interrupts disabled.

It shouldn't be a problem for rxrpc_new_incoming_call() to do it after the
locks are dropped as pmtud is going to be performed by the I/O thread - and
we're in the I/O thread at this point.

Fixes: a2ea9a907260 ("rxrpc: Use irq-disabling spinlocks between app and I/O thread")
Signed-off-by: David Howells &lt;dhowells@redhat.com&gt;
Reviewed-by: Jeffrey Altman &lt;jaltman@auristor.com&gt;
cc: Marc Dionne &lt;marc.dionne@auristor.com&gt;
cc: Junvyyang, Tencent Zhuque Lab &lt;zhuque@tencent.com&gt;
cc: LePremierHomme &lt;kwqcheii@proton.me&gt;
cc: Simon Horman &lt;horms@kernel.org&gt;
cc: linux-afs@lists.infradead.org
Link: https://patch.msgid.link/20250717074350.3767366-2-dhowells@redhat.com
Signed-off-by: Jakub Kicinski &lt;kuba@kernel.org&gt;
</content>
</entry>
<entry>
<title>net/sched: Return NULL when htb_lookup_leaf encounters an empty rbtree</title>
<updated>2025-07-17T14:47:55Z</updated>
<author>
<name>William Liu</name>
<email>will@willsroot.io</email>
</author>
<published>2025-07-17T02:28:38Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/linux/commit/?id=0e1d5d9b5c5966e2e42e298670808590db5ed628'/>
<id>urn:sha1:0e1d5d9b5c5966e2e42e298670808590db5ed628</id>
<content type='text'>
htb_lookup_leaf has a BUG_ON that can trigger with the following:

tc qdisc del dev lo root
tc qdisc add dev lo root handle 1: htb default 1
tc class add dev lo parent 1: classid 1:1 htb rate 64bit
tc qdisc add dev lo parent 1:1 handle 2: netem
tc qdisc add dev lo parent 2:1 handle 3: blackhole
ping -I lo -c1 -W0.001 127.0.0.1

The root cause is the following:

1. htb_dequeue calls htb_dequeue_tree which calls the dequeue handler on
   the selected leaf qdisc
2. netem_dequeue calls enqueue on the child qdisc
3. blackhole_enqueue drops the packet and returns a value that is not
   just NET_XMIT_SUCCESS
4. Because of this, netem_dequeue calls qdisc_tree_reduce_backlog, and
   since qlen is now 0, it calls htb_qlen_notify -&gt; htb_deactivate -&gt;
   htb_deactiviate_prios -&gt; htb_remove_class_from_row -&gt; htb_safe_rb_erase
5. As this is the only class in the selected hprio rbtree,
   __rb_change_child in __rb_erase_augmented sets the rb_root pointer to
   NULL
6. Because blackhole_dequeue returns NULL, netem_dequeue returns NULL,
   which causes htb_dequeue_tree to call htb_lookup_leaf with the same
   hprio rbtree, and fail the BUG_ON

The function graph for this scenario is shown here:
 0)               |  htb_enqueue() {
 0) + 13.635 us   |    netem_enqueue();
 0)   4.719 us    |    htb_activate_prios();
 0) # 2249.199 us |  }
 0)               |  htb_dequeue() {
 0)   2.355 us    |    htb_lookup_leaf();
 0)               |    netem_dequeue() {
 0) + 11.061 us   |      blackhole_enqueue();
 0)               |      qdisc_tree_reduce_backlog() {
 0)               |        qdisc_lookup_rcu() {
 0)   1.873 us    |          qdisc_match_from_root();
 0)   6.292 us    |        }
 0)   1.894 us    |        htb_search();
 0)               |        htb_qlen_notify() {
 0)   2.655 us    |          htb_deactivate_prios();
 0)   6.933 us    |        }
 0) + 25.227 us   |      }
 0)   1.983 us    |      blackhole_dequeue();
 0) + 86.553 us   |    }
 0) # 2932.761 us |    qdisc_warn_nonwc();
 0)               |    htb_lookup_leaf() {
 0)               |      BUG_ON();
 ------------------------------------------

The full original bug report can be seen here [1].

We can fix this just by returning NULL instead of the BUG_ON,
as htb_dequeue_tree returns NULL when htb_lookup_leaf returns
NULL.

[1] https://lore.kernel.org/netdev/pF5XOOIim0IuEfhI-SOxTgRvNoDwuux7UHKnE_Y5-zVd4wmGvNk2ceHjKb8ORnzw0cGwfmVu42g9dL7XyJLf1NEzaztboTWcm0Ogxuojoeo=@willsroot.io/

Fixes: 512bb43eb542 ("pkt_sched: sch_htb: Optimize WARN_ONs in htb_dequeue_tree() etc.")
Signed-off-by: William Liu &lt;will@willsroot.io&gt;
Signed-off-by: Savino Dicanosa &lt;savy@syst3mfailure.io&gt;
Link: https://patch.msgid.link/20250717022816.221364-1-will@willsroot.io
Signed-off-by: Jakub Kicinski &lt;kuba@kernel.org&gt;
</content>
</entry>
</feed>
