48f65f6
From a08748fb2221ef03d54071e5ddfcc1b0cee6961c Mon Sep 17 00:00:00 2001
48f65f6
From: Tejun Heo <tj@kernel.org>
48f65f6
Date: Sat, 5 Sep 2015 15:47:36 -0400
48f65f6
Subject: [PATCH] block: blkg_destroy_all() should clear q->root_blkg and
48f65f6
 ->root_rl.blkg
48f65f6
48f65f6
While making the root blkg unconditional, ec13b1d6f0a0 ("blkcg: always
48f65f6
create the blkcg_gq for the root blkcg") removed the part which clears
48f65f6
q->root_blkg and ->root_rl.blkg during q exit.  This leaves the two
48f65f6
pointers dangling after blkg_destroy_all().  blk-throttle exit path
48f65f6
performs blkg traversals and dereferences ->root_blkg and can lead to
48f65f6
the following oops.
48f65f6
48f65f6
 BUG: unable to handle kernel NULL pointer dereference at 0000000000000558
48f65f6
 IP: [<ffffffff81389746>] __blkg_lookup+0x26/0x70
48f65f6
 ...
48f65f6
 task: ffff88001b4e2580 ti: ffff88001ac0c000 task.ti: ffff88001ac0c000
48f65f6
 RIP: 0010:[<ffffffff81389746>]  [<ffffffff81389746>] __blkg_lookup+0x26/0x70
48f65f6
 ...
48f65f6
 Call Trace:
48f65f6
  [<ffffffff8138d14a>] blk_throtl_drain+0x5a/0x110
48f65f6
  [<ffffffff8138a108>] blkcg_drain_queue+0x18/0x20
48f65f6
  [<ffffffff81369a70>] __blk_drain_queue+0xc0/0x170
48f65f6
  [<ffffffff8136a101>] blk_queue_bypass_start+0x61/0x80
48f65f6
  [<ffffffff81388c59>] blkcg_deactivate_policy+0x39/0x100
48f65f6
  [<ffffffff8138d328>] blk_throtl_exit+0x38/0x50
48f65f6
  [<ffffffff8138a14e>] blkcg_exit_queue+0x3e/0x50
48f65f6
  [<ffffffff8137016e>] blk_release_queue+0x1e/0xc0
48f65f6
 ...
48f65f6
48f65f6
While the bug is a straigh-forward use-after-free bug, it is tricky to
48f65f6
reproduce because blkg release is RCU protected and the rest of exit
48f65f6
path usually finishes before RCU grace period.
48f65f6
48f65f6
This patch fixes the bug by updating blkg_destro_all() to clear
48f65f6
q->root_blkg and ->root_rl.blkg.
48f65f6
48f65f6
Signed-off-by: Tejun Heo <tj@kernel.org>
48f65f6
Reported-by: "Richard W.M. Jones" <rjones@redhat.com>
48f65f6
Reported-by: Josh Boyer <jwboyer@fedoraproject.org>
48f65f6
Link: http://lkml.kernel.org/g/CA+5PVA5rzQ0s4723n5rHBcxQa9t0cW8BPPBekr_9aMRoWt2aYg@mail.gmail.com
48f65f6
Fixes: ec13b1d6f0a0 ("blkcg: always create the blkcg_gq for the root blkcg")
48f65f6
Cc: stable@vger.kernel.org # v4.2+
48f65f6
---
48f65f6
 block/blk-cgroup.c | 3 +++
48f65f6
 1 file changed, 3 insertions(+)
48f65f6
48f65f6
diff --git a/block/blk-cgroup.c b/block/blk-cgroup.c
48f65f6
index d6283b3f5db5..9cc48d1d7abb 100644
48f65f6
--- a/block/blk-cgroup.c
48f65f6
+++ b/block/blk-cgroup.c
48f65f6
@@ -387,6 +387,9 @@ static void blkg_destroy_all(struct request_queue *q)
48f65f6
 		blkg_destroy(blkg);
48f65f6
 		spin_unlock(&blkcg->lock);
48f65f6
 	}
48f65f6
+
48f65f6
+	q->root_blkg = NULL;
48f65f6
+	q->root_rl.blkg = NULL;
48f65f6
 }
48f65f6
 
48f65f6
 /*
48f65f6
-- 
48f65f6
2.4.3
48f65f6