block: blk_init_allocated_queue() set q->fq as NULL in the fail case [Linux 4.9.189]

This Linux kernel change "block: blk_init_allocated_queue() set q->fq as NULL in the fail case" is included in the Linux 4.9.189 release. This change is authored by xiao jin <jin.xiao [at]> on Mon Jul 30 14:11:12 2018 +0800. The commit for this change in Linux stable tree is c191991 (patch) which is from upstream commit 54648cf. The same Linux upstream change may have been applied to various maintained Linux releases and you can find all Linux releases containing changes from upstream 54648cf.

block: blk_init_allocated_queue() set q->fq as NULL in the fail case

commit 54648cf1ec2d7f4b6a71767799c45676a138ca24 upstream.

We find the memory use-after-free issue in __blk_drain_queue()
on the kernel 4.14. After read the latest kernel 4.18-rc6 we
think it has the same problem.

Memory is allocated for q->fq in the blk_init_allocated_queue().
If the elevator init function called with error return, it will
run into the fail case to free the q->fq.

Then the __blk_drain_queue() uses the same memory after the free
of the q->fq, it will lead to the unpredictable event.

The patch is to set q->fq as NULL in the fail case of

Fixes: commit 7c94e1c157a2 ("block: introduce blk_flush_queue to drive flush machinery")
Cc: <[email protected]>
Reviewed-by: Ming Lei <[email protected]>
Reviewed-by: Bart Van Assche <[email protected]>
Signed-off-by: xiao jin <[email protected]>
Signed-off-by: Jens Axboe <[email protected]>
[groeck: backport to v4.4.y/v4.9.y (context change)]
Signed-off-by: Guenter Roeck <[email protected]>
Signed-off-by: Alessio Balsini <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>

There is one line of Linux source code added/deleted in this change. Code changes to Linux kernel are as follows.

 block/blk-core.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/block/blk-core.c b/block/blk-core.c
index 77b99bf..bdb906b 100644
--- a/block/blk-core.c
+++ b/block/blk-core.c
@@ -881,6 +881,7 @@ struct request_queue *

+   q->fq = NULL;
    return NULL;

Leave a Reply

Your email address will not be published. Required fields are marked *