> Il giorno 10 mar 2021, alle ore 04:15, lyl2019@xxxxxxxxxxxxxxxx ha scritto: > > File: block/bfq-wf2q.c > > There exist a feasible path to trigger a use after free bug in > bfq_del_bfqq_busy, since v4.12-rc1. It could cause denial of service. > Thank you very much for analyzing this. > In the implemention of bfq_del_bfqq_busy, I've checked all invocations of bfq_del_bfqq_busy, comments below. > it calls bfq_deactivate_bfqq() > and use `bfqq` later. Whereas bfq_deactivate_bfqq() could free `bfqq`. > > The trigger path is as follow: > |- bfq_deactivate_bfqq(.., bfqq, true, ..) > |-- entity = &bfqq->entity; // get entity > |-- bfq_deactivate_entity(entity, true, ...); //has a path to free `bfqq` > |-- if (!bfqq->dispatched) // use after free! > > > |- bfq_deactivate_entity(entity, true, ...) > |-- ... > |-- for_each_entity_safe(entity, parent) { // in the first loop, > //entity is the same as before > if (!__bfq_deactivate_entity(entity, true)) { > > |- __bfq_deactivate_entity(entity, true) > |-- ... > |-- if (!ins_into_idle_tree || !bfq_gt(entity->finish, st->vtime)) > bfq_forget_entity(st, entity, is_in_service); > > |- bfq_forget_entity(st, entity, is_in_service) > |-- bfqq = bfq_entity_to_bfqq(entity); // recover `bfqq` by entity > |-- if (bfqq && !is_in_service) > bfq_put_queue(bfqq); // free the `bfqq` > For this put to turn into a free, bfqq should have only one ref. But I did not find any invocation of bfq_del_bfqq_busy with bfqq->ref == 1. Did you spot any? Looking forward to your feedback, Paolo > The bug fix needs to add some checks to avoid freeing `bfqq` in the first > loop in __bfq_deactivate_entity(). I can't come out a good patch for it, > so i report it for you.