From: Oleg Nesterov <o...@redhat.com>

commit 8751853091998cd31e9e5f1e8206280155af8921 upstream.

swap_readpage() sets waiter = bio->bi_private even if synchronous = F,
this means that the caller can get the spurious wakeup after return.

This can be fatal if blk_wake_io_task() does
set_current_state(TASK_RUNNING) after the caller does
set_special_state(), in the worst case the kernel can crash in
do_task_dead().

Link: http://lkml.kernel.org/r/20190704160301.ga5...@redhat.com
Fixes: 0619317ff8baa2d ("block: add polled wakeup task helper")
Signed-off-by: Oleg Nesterov <o...@redhat.com>
Reported-by: Qian Cai <c...@lca.pw>
Acked-by: Hugh Dickins <hu...@google.com>
Reviewed-by: Jens Axboe <ax...@kernel.dk>
Cc: <sta...@vger.kernel.org>
Signed-off-by: Andrew Morton <a...@linux-foundation.org>
Signed-off-by: Linus Torvalds <torva...@linux-foundation.org>
Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org>

---
 mm/page_io.c |   13 ++++++++-----
 1 file changed, 8 insertions(+), 5 deletions(-)

--- a/mm/page_io.c
+++ b/mm/page_io.c
@@ -137,8 +137,10 @@ out:
        unlock_page(page);
        WRITE_ONCE(bio->bi_private, NULL);
        bio_put(bio);
-       blk_wake_io_task(waiter);
-       put_task_struct(waiter);
+       if (waiter) {
+               blk_wake_io_task(waiter);
+               put_task_struct(waiter);
+       }
 }
 
 int generic_swapfile_activate(struct swap_info_struct *sis,
@@ -395,11 +397,12 @@ int swap_readpage(struct page *page, boo
         * Keep this task valid during swap readpage because the oom killer may
         * attempt to access it in the page fault retry time check.
         */
-       get_task_struct(current);
-       bio->bi_private = current;
        bio_set_op_attrs(bio, REQ_OP_READ, 0);
-       if (synchronous)
+       if (synchronous) {
                bio->bi_opf |= REQ_HIPRI;
+               get_task_struct(current);
+               bio->bi_private = current;
+       }
        count_vm_event(PSWPIN);
        bio_get(bio);
        qc = submit_bio(bio);


Reply via email to