diff options
author | Paolo Valente <paolo.valente@linaro.org> | 2019-04-10 10:38:33 +0200 |
---|---|---|
committer | Jens Axboe <axboe@kernel.dk> | 2019-04-10 07:54:38 -0600 |
commit | eed47d19d9362bdd958e4ab56af480b9dbf6b2b6 (patch) | |
tree | ebb19cdcb30d8e16135544007babceb40da2d08b /fs/aio.c | |
parent | 3ec482d15cb986bf08b923f9193eeddb3b9ca69f (diff) | |
download | linux-eed47d19d9362bdd958e4ab56af480b9dbf6b2b6.tar.gz |
block, bfq: fix use after free in bfq_bfqq_expire
The function bfq_bfqq_expire() invokes the function __bfq_bfqq_expire(), and the latter may free the in-service bfq-queue. If this happens, then no other instruction of bfq_bfqq_expire() must be executed, or a use-after-free will occur. Basing on the assumption that __bfq_bfqq_expire() invokes bfq_put_queue() on the in-service bfq-queue exactly once, the queue is assumed to be freed if its refcounter is equal to one right before invoking __bfq_bfqq_expire(). But, since commit 9dee8b3b057e ("block, bfq: fix queue removal from weights tree") this assumption is false. __bfq_bfqq_expire() may also invoke bfq_weights_tree_remove() and, since commit 9dee8b3b057e ("block, bfq: fix queue removal from weights tree"), also the latter function may invoke bfq_put_queue(). So __bfq_bfqq_expire() may invoke bfq_put_queue() twice, and this is the actual case where the in-service queue may happen to be freed. To address this issue, this commit moves the check on the refcounter of the queue right around the last bfq_put_queue() that may be invoked on the queue. Fixes: 9dee8b3b057e ("block, bfq: fix queue removal from weights tree") Reported-by: Dmitrii Tcvetkov <demfloro@demfloro.ru> Reported-by: Douglas Anderson <dianders@chromium.org> Tested-by: Dmitrii Tcvetkov <demfloro@demfloro.ru> Tested-by: Douglas Anderson <dianders@chromium.org> Signed-off-by: Paolo Valente <paolo.valente@linaro.org> Signed-off-by: Jens Axboe <axboe@kernel.dk>
Diffstat (limited to 'fs/aio.c')
0 files changed, 0 insertions, 0 deletions