Commit 21974061 authored by Mike Krinkin's avatar Mike Krinkin Committed by Jens Axboe

null_blk: fix use-after-free problem

end_cmd finishes request associated with nullb_cmd struct, so we
should save pointer to request_queue in a local variable before
calling end_cmd.

The problem was causes general protection fault with slab poisoning
enabled.

Fixes: 8b70f45e ("null_blk: restart request processing on completion handler")
Tested-by: default avatarAkinobu Mita <akinobu.mita@gmail.com>
Signed-off-by: default avatarMike Krinkin <krinkin.m.u@gmail.com>
Signed-off-by: default avatarJens Axboe <axboe@fb.com>
parent d725e66c
...@@ -240,19 +240,19 @@ static enum hrtimer_restart null_cmd_timer_expired(struct hrtimer *timer) ...@@ -240,19 +240,19 @@ static enum hrtimer_restart null_cmd_timer_expired(struct hrtimer *timer)
while ((entry = llist_del_all(&cq->list)) != NULL) { while ((entry = llist_del_all(&cq->list)) != NULL) {
entry = llist_reverse_order(entry); entry = llist_reverse_order(entry);
do { do {
struct request_queue *q = NULL;
cmd = container_of(entry, struct nullb_cmd, ll_list); cmd = container_of(entry, struct nullb_cmd, ll_list);
entry = entry->next; entry = entry->next;
if (cmd->rq)
q = cmd->rq->q;
end_cmd(cmd); end_cmd(cmd);
if (cmd->rq) { if (q && !q->mq_ops && blk_queue_stopped(q)) {
struct request_queue *q = cmd->rq->q; spin_lock(q->queue_lock);
if (blk_queue_stopped(q))
if (!q->mq_ops && blk_queue_stopped(q)) { blk_start_queue(q);
spin_lock(q->queue_lock); spin_unlock(q->queue_lock);
if (blk_queue_stopped(q))
blk_start_queue(q);
spin_unlock(q->queue_lock);
}
} }
} while (entry); } while (entry);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment