blk-mq: Do not invoke queue operations on a dead queue
authorBart Van Assche <bart.vanassche@sandisk.com>
Thu, 4 May 2017 07:31:29 +0000 (00:31 -0700)
committerJens Axboe <axboe@fb.com>
Thu, 4 May 2017 14:23:39 +0000 (08:23 -0600)
In commit e869b5462f83 ("blk-mq: Unregister debugfs attributes
earlier"), we shuffled the debugfs cleanup around so that the "state"
attribute was removed before we freed the blk-mq data structures.
However, later changes are going to undo that, so we need to explicitly
disallow running a dead queue.

[Omar: rebased and updated commit message]
Signed-off-by: Omar Sandoval <osandov@fb.com>
Signed-off-by: Bart Van Assche <bart.vanassche@sandisk.com>
Reviewed-by: Hannes Reinecke <hare@suse.com>
Signed-off-by: Jens Axboe <axboe@fb.com>
block/blk-mq-debugfs.c

index 1579af6fcbedcd6c9375687a48a4791e5d756b56..347fbb8e059cf3e3e45b5b8071fa529f94038835 100644 (file)
@@ -102,6 +102,14 @@ static ssize_t queue_state_write(void *data, const char __user *buf,
        struct request_queue *q = data;
        char opbuf[16] = { }, *op;
 
+       /*
+        * The "state" attribute is removed after blk_cleanup_queue() has called
+        * blk_mq_free_queue(). Return if QUEUE_FLAG_DEAD has been set to avoid
+        * triggering a use-after-free.
+        */
+       if (blk_queue_dead(q))
+               return -ENOENT;
+
        if (count >= sizeof(opbuf)) {
                pr_err("%s: operation too long\n", __func__);
                goto inval;