summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorJan Kara <jack@suse.cz>2020-02-06 15:28:12 +0100
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2020-05-20 08:11:38 +0200
commit3d5d64aea941a45efda1bd02c0ec8dd57e8ce4ca (patch)
tree6923d6ae1362d3e0765ab06580c17b7f09c2bae0 /include
parentcd13258a62313ca9102116d57340d76453297b09 (diff)
blktrace: Protect q->blk_trace with RCU
commit c780e86dd48ef6467a1146cf7d0fe1e05a635039 upstream. KASAN is reporting that __blk_add_trace() has a use-after-free issue when accessing q->blk_trace. Indeed the switching of block tracing (and thus eventual freeing of q->blk_trace) is completely unsynchronized with the currently running tracing and thus it can happen that the blk_trace structure is being freed just while __blk_add_trace() works on it. Protect accesses to q->blk_trace by RCU during tracing and make sure we wait for the end of RCU grace period when shutting down tracing. Luckily that is rare enough event that we can afford that. Note that postponing the freeing of blk_trace to an RCU callback should better be avoided as it could have unexpected user visible side-effects as debugfs files would be still existing for a short while block tracing has been shut down. Link: https://bugzilla.kernel.org/show_bug.cgi?id=205711 CC: stable@vger.kernel.org Reviewed-by: Chaitanya Kulkarni <chaitanya.kulkarni@wdc.com> Reviewed-by: Ming Lei <ming.lei@redhat.com> Tested-by: Ming Lei <ming.lei@redhat.com> Reviewed-by: Bart Van Assche <bvanassche@acm.org> Reported-by: Tristan Madani <tristmd@gmail.com> Signed-off-by: Jan Kara <jack@suse.cz> Signed-off-by: Jens Axboe <axboe@kernel.dk> [bwh: Backported to 4.4: - Drop changes in blk_trace_note_message_enabled(), blk_trace_bio_get_cgid() - Adjust context] Signed-off-by: Ben Hutchings <ben.hutchings@codethink.co.uk> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'include')
-rw-r--r--include/linux/blkdev.h2
-rw-r--r--include/linux/blktrace_api.h6
2 files changed, 6 insertions, 2 deletions
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index ab819210e011..6e83ea61436a 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -431,7 +431,7 @@ struct request_queue {
unsigned int sg_reserved_size;
int node;
#ifdef CONFIG_BLK_DEV_IO_TRACE
- struct blk_trace *blk_trace;
+ struct blk_trace __rcu *blk_trace;
struct mutex blk_trace_mutex;
#endif
/*
diff --git a/include/linux/blktrace_api.h b/include/linux/blktrace_api.h
index afc1343df3c7..e644bfe50019 100644
--- a/include/linux/blktrace_api.h
+++ b/include/linux/blktrace_api.h
@@ -51,9 +51,13 @@ void __trace_note_message(struct blk_trace *, const char *fmt, ...);
**/
#define blk_add_trace_msg(q, fmt, ...) \
do { \
- struct blk_trace *bt = (q)->blk_trace; \
+ struct blk_trace *bt; \
+ \
+ rcu_read_lock(); \
+ bt = rcu_dereference((q)->blk_trace); \
if (unlikely(bt)) \
__trace_note_message(bt, fmt, ##__VA_ARGS__); \
+ rcu_read_unlock(); \
} while (0)
#define BLK_TN_MAX_MSG 128