Patch "net/sched: sch_taprio: fix possible use-after-free" has been added to the 5.4-stable tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is a note to let you know that I've just added the patch titled

    net/sched: sch_taprio: fix possible use-after-free

to the 5.4-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     net-sched-sch_taprio-fix-possible-use-after-free.patch
and it can be found in the queue-5.4 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@xxxxxxxxxxxxxxx> know about it.



commit 53a41f472aa8c2e086fe9308f0d34bf9d1d4c320
Author: Eric Dumazet <edumazet@xxxxxxxxxx>
Date:   Fri Jan 13 16:48:49 2023 +0000

    net/sched: sch_taprio: fix possible use-after-free
    
    [ Upstream commit 3a415d59c1dbec9d772dbfab2d2520d98360caae ]
    
    syzbot reported a nasty crash [1] in net_tx_action() which
    made little sense until we got a repro.
    
    This repro installs a taprio qdisc, but providing an
    invalid TCA_RATE attribute.
    
    qdisc_create() has to destroy the just initialized
    taprio qdisc, and taprio_destroy() is called.
    
    However, the hrtimer used by taprio had already fired,
    therefore advance_sched() called __netif_schedule().
    
    Then net_tx_action was trying to use a destroyed qdisc.
    
    We can not undo the __netif_schedule(), so we must wait
    until one cpu serviced the qdisc before we can proceed.
    
    Many thanks to Alexander Potapenko for his help.
    
    [1]
    BUG: KMSAN: uninit-value in queued_spin_trylock include/asm-generic/qspinlock.h:94 [inline]
    BUG: KMSAN: uninit-value in do_raw_spin_trylock include/linux/spinlock.h:191 [inline]
    BUG: KMSAN: uninit-value in __raw_spin_trylock include/linux/spinlock_api_smp.h:89 [inline]
    BUG: KMSAN: uninit-value in _raw_spin_trylock+0x92/0xa0 kernel/locking/spinlock.c:138
     queued_spin_trylock include/asm-generic/qspinlock.h:94 [inline]
     do_raw_spin_trylock include/linux/spinlock.h:191 [inline]
     __raw_spin_trylock include/linux/spinlock_api_smp.h:89 [inline]
     _raw_spin_trylock+0x92/0xa0 kernel/locking/spinlock.c:138
     spin_trylock include/linux/spinlock.h:359 [inline]
     qdisc_run_begin include/net/sch_generic.h:187 [inline]
     qdisc_run+0xee/0x540 include/net/pkt_sched.h:125
     net_tx_action+0x77c/0x9a0 net/core/dev.c:5086
     __do_softirq+0x1cc/0x7fb kernel/softirq.c:571
     run_ksoftirqd+0x2c/0x50 kernel/softirq.c:934
     smpboot_thread_fn+0x554/0x9f0 kernel/smpboot.c:164
     kthread+0x31b/0x430 kernel/kthread.c:376
     ret_from_fork+0x1f/0x30
    
    Uninit was created at:
     slab_post_alloc_hook mm/slab.h:732 [inline]
     slab_alloc_node mm/slub.c:3258 [inline]
     __kmalloc_node_track_caller+0x814/0x1250 mm/slub.c:4970
     kmalloc_reserve net/core/skbuff.c:358 [inline]
     __alloc_skb+0x346/0xcf0 net/core/skbuff.c:430
     alloc_skb include/linux/skbuff.h:1257 [inline]
     nlmsg_new include/net/netlink.h:953 [inline]
     netlink_ack+0x5f3/0x12b0 net/netlink/af_netlink.c:2436
     netlink_rcv_skb+0x55d/0x6c0 net/netlink/af_netlink.c:2507
     rtnetlink_rcv+0x30/0x40 net/core/rtnetlink.c:6108
     netlink_unicast_kernel net/netlink/af_netlink.c:1319 [inline]
     netlink_unicast+0xf3b/0x1270 net/netlink/af_netlink.c:1345
     netlink_sendmsg+0x1288/0x1440 net/netlink/af_netlink.c:1921
     sock_sendmsg_nosec net/socket.c:714 [inline]
     sock_sendmsg net/socket.c:734 [inline]
     ____sys_sendmsg+0xabc/0xe90 net/socket.c:2482
     ___sys_sendmsg+0x2a1/0x3f0 net/socket.c:2536
     __sys_sendmsg net/socket.c:2565 [inline]
     __do_sys_sendmsg net/socket.c:2574 [inline]
     __se_sys_sendmsg net/socket.c:2572 [inline]
     __x64_sys_sendmsg+0x367/0x540 net/socket.c:2572
     do_syscall_x64 arch/x86/entry/common.c:50 [inline]
     do_syscall_64+0x3d/0xb0 arch/x86/entry/common.c:80
     entry_SYSCALL_64_after_hwframe+0x63/0xcd
    
    CPU: 0 PID: 13 Comm: ksoftirqd/0 Not tainted 6.0.0-rc2-syzkaller-47461-gac3859c02d7f #0
    Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 07/22/2022
    
    Fixes: 5a781ccbd19e ("tc: Add support for configuring the taprio scheduler")
    Reported-by: syzbot <syzkaller@xxxxxxxxxxxxxxxx>
    Signed-off-by: Eric Dumazet <edumazet@xxxxxxxxxx>
    Cc: Alexander Potapenko <glider@xxxxxxxxxx>
    Cc: Vinicius Costa Gomes <vinicius.gomes@xxxxxxxxx>
    Signed-off-by: David S. Miller <davem@xxxxxxxxxxxxx>
    Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h
index 1ee396ce0eda..e8034756cbf8 100644
--- a/include/net/sch_generic.h
+++ b/include/net/sch_generic.h
@@ -1334,4 +1334,11 @@ static inline void skb_tc_reinsert(struct sk_buff *skb, struct tcf_result *res)
 		qstats_overlimit_inc(res->qstats);
 }
 
+/* Make sure qdisc is no longer in SCHED state. */
+static inline void qdisc_synchronize(const struct Qdisc *q)
+{
+	while (test_bit(__QDISC_STATE_SCHED, &q->state))
+		msleep(1);
+}
+
 #endif
diff --git a/net/sched/sch_taprio.c b/net/sched/sch_taprio.c
index 506ebae1f72c..4278a466cb50 100644
--- a/net/sched/sch_taprio.c
+++ b/net/sched/sch_taprio.c
@@ -1622,6 +1622,8 @@ static void taprio_reset(struct Qdisc *sch)
 	int i;
 
 	hrtimer_cancel(&q->advance_timer);
+	qdisc_synchronize(sch);
+
 	if (q->qdiscs) {
 		for (i = 0; i < dev->num_tx_queues && q->qdiscs[i]; i++)
 			qdisc_reset(q->qdiscs[i]);
@@ -1644,6 +1646,7 @@ static void taprio_destroy(struct Qdisc *sch)
 	 * happens in qdisc_create(), after taprio_init() has been called.
 	 */
 	hrtimer_cancel(&q->advance_timer);
+	qdisc_synchronize(sch);
 
 	taprio_disable_offload(dev, q, NULL);
 



[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux