lkml.org 
[lkml]   [2021]   [Jan]   [4]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.4 01/47] net/sched: sch_taprio: reset child qdiscs before freeing them
    Date
    From: Davide Caratti <dcaratti@redhat.com>

    [ Upstream commit 44d4775ca51805b376a8db5b34f650434a08e556 ]

    syzkaller shows that packets can still be dequeued while taprio_destroy()
    is running. Let sch_taprio use the reset() function to cancel the advance
    timer and drop all skbs from the child qdiscs.

    Fixes: 5a781ccbd19e ("tc: Add support for configuring the taprio scheduler")
    Link: https://syzkaller.appspot.com/bug?id=f362872379bf8f0017fb667c1ab158f2d1e764ae
    Reported-by: syzbot+8971da381fb5a31f542d@syzkaller.appspotmail.com
    Signed-off-by: Davide Caratti <dcaratti@redhat.com>
    Acked-by: Vinicius Costa Gomes <vinicius.gomes@intel.com>
    Link: https://lore.kernel.org/r/63b6d79b0e830ebb0283e020db4df3cdfdfb2b94.1608142843.git.dcaratti@redhat.com
    Signed-off-by: Jakub Kicinski <kuba@kernel.org>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
    ---
    net/sched/sch_taprio.c | 17 ++++++++++++++++-
    1 file changed, 16 insertions(+), 1 deletion(-)

    --- a/net/sched/sch_taprio.c
    +++ b/net/sched/sch_taprio.c
    @@ -1597,6 +1597,21 @@ free_sched:
    return err;
    }

    +static void taprio_reset(struct Qdisc *sch)
    +{
    + struct taprio_sched *q = qdisc_priv(sch);
    + struct net_device *dev = qdisc_dev(sch);
    + int i;
    +
    + hrtimer_cancel(&q->advance_timer);
    + if (q->qdiscs) {
    + for (i = 0; i < dev->num_tx_queues && q->qdiscs[i]; i++)
    + qdisc_reset(q->qdiscs[i]);
    + }
    + sch->qstats.backlog = 0;
    + sch->q.qlen = 0;
    +}
    +
    static void taprio_destroy(struct Qdisc *sch)
    {
    struct taprio_sched *q = qdisc_priv(sch);
    @@ -1607,7 +1622,6 @@ static void taprio_destroy(struct Qdisc
    list_del(&q->taprio_list);
    spin_unlock(&taprio_list_lock);

    - hrtimer_cancel(&q->advance_timer);

    taprio_disable_offload(dev, q, NULL);

    @@ -1954,6 +1968,7 @@ static struct Qdisc_ops taprio_qdisc_ops
    .init = taprio_init,
    .change = taprio_change,
    .destroy = taprio_destroy,
    + .reset = taprio_reset,
    .peek = taprio_peek,
    .dequeue = taprio_dequeue,
    .enqueue = taprio_enqueue,

    \
     
     \ /
      Last update: 2021-01-04 17:02    [W:8.248 / U:0.012 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site