Description
In the Linux kernel, the following vulnerability has been resolved: net/sched: sch_teql: Introduce slaves_lock to avoid race condition and UAF The teql master->slaves singly linked list is not protected against multiple writes. It can be mod'ed concurently from teql_master_xmit(), teql_dequeue(), teql_init() and teql_destroy() without holding any list lock or RCU protection. zdi-disclosures@trendmicro.com has demonstrated that the qdisc is freed after an RCU grace period, but teql_master_xmit() running on another CPU can still hold a stale pointer into the list, resulting in a slab-use-after-free: BUG: KASAN: slab-use-after-free in teql_master_xmit+0xf0f/0x16b0 Read of size 8 at addr ffff888013fb0440 by task poc/332 Freed 512-byte region [ffff888013fb0400, ffff888013fb0600) (kmalloc-512) The fix? Add a per-master slaves_lock spinlock that serializes all mutations of master->slaves and the NEXT_SLAVE() links in teql_destroy() and teql_qdisc_init(). teql_master_xmit() also takes the same slaves_lock around those updates. Annotate master->slaves and the per-slave ->next pointer with __rcu and use the appropriate RCU accessors everywhere they are touched: rcu_assign_pointer() on the writer side (under slaves_lock), rcu_dereference_protected() for the writer-side loads (also under slaves_lock), rcu_dereference_bh() for the loads in teql_master_xmit() and rtnl_dereference() for the loads in teql_master_open()/teql_master_mtu(), which run under RTNL. Pair this with rcu_read_lock_bh()/rcu_read_unlock_bh() around the list traversal in teql_master_xmit(), so that readers either observe a fully linked list or are deferred until the in-flight mutation completes. The two early-return paths in teql_master_xmit() are updated to release the RCU-bh read-side critical section before returning, since leaving it held would disable BH on that CPU for good.
Affected products
Version statuses are supplied by the assigning organization. Consult the original record for detailed ranges and platform conditions.
Linux Linux
Default version status: unaffected
1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 to < 03c67781254c574ae7fa75e881239a78473bdf42affected1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 to < 735567bde7401f82b064f9f107b52ee1bf84ed8caffected1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 to < 11402e6e18e96df615cbcc58157818dd604b23ffaffected1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 to < 9b7d05cbaa60108642402100efa6aa288dd33023affected1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 to < b26aa9d993537a4c3167d8ceead3b7c69c3a0aacaffected1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 to < e5b811fe793166aecc59b085c1b7c31262ef2316affected
Linux Linux
Default version status: affected
2.6.12affected0 to < 2.6.12unaffected6.1.178 to ≤ 6.1.*unaffected6.6.145 to ≤ 6.6.*unaffected6.12.97 to ≤ 6.12.*unaffected6.18.40 to ≤ 6.18.*unaffected7.1.5 to ≤ 7.1.*unaffected7.2 to ≤ *unaffected
References
- https://git.kernel.org/stable/c/03c67781254c574ae7fa75e881239a78473bdf42 ↗
- https://git.kernel.org/stable/c/735567bde7401f82b064f9f107b52ee1bf84ed8c ↗
- https://git.kernel.org/stable/c/11402e6e18e96df615cbcc58157818dd604b23ff ↗
- https://git.kernel.org/stable/c/9b7d05cbaa60108642402100efa6aa288dd33023 ↗
- https://git.kernel.org/stable/c/b26aa9d993537a4c3167d8ceead3b7c69c3a0aac ↗
- https://git.kernel.org/stable/c/e5b811fe793166aecc59b085c1b7c31262ef2316 ↗