Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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: 8b70f45e2eb2 ("null_blk: restart request processing on completion handler")
Tested-by: Akinobu Mita <akinobu.mita@gmail.com>
Signed-off-by: Mike Krinkin <krinkin.m.u@gmail.com>
Signed-off-by: Jens Axboe <axboe@fb.com>

authored by

Mike Krinkin and committed by
Jens Axboe
21974061 d725e66c

+9 -9
+9 -9
drivers/block/null_blk.c
··· 240 240 while ((entry = llist_del_all(&cq->list)) != NULL) { 241 241 entry = llist_reverse_order(entry); 242 242 do { 243 + struct request_queue *q = NULL; 244 + 243 245 cmd = container_of(entry, struct nullb_cmd, ll_list); 244 246 entry = entry->next; 247 + if (cmd->rq) 248 + q = cmd->rq->q; 245 249 end_cmd(cmd); 246 250 247 - if (cmd->rq) { 248 - struct request_queue *q = cmd->rq->q; 249 - 250 - if (!q->mq_ops && blk_queue_stopped(q)) { 251 - spin_lock(q->queue_lock); 252 - if (blk_queue_stopped(q)) 253 - blk_start_queue(q); 254 - spin_unlock(q->queue_lock); 255 - } 251 + if (q && !q->mq_ops && blk_queue_stopped(q)) { 252 + spin_lock(q->queue_lock); 253 + if (blk_queue_stopped(q)) 254 + blk_start_queue(q); 255 + spin_unlock(q->queue_lock); 256 256 } 257 257 } while (entry); 258 258 }