On 3/3/20 9:35 PM, Steven Rostedt wrote: > On Tue, 3 Mar 2020 21:29:08 +0800 > Bob Liu <bob.liu@xxxxxxxxxx> wrote: > >> On 3/3/20 3:33 PM, Cengiz Can wrote: >>> There was a recent change in blktrace.c that added a RCU protection to >>> `q->blk_trace` in order to fix a use-after-free issue during access. >>> >>> However the change missed an edge case that can lead to dereferencing of >>> `bt` pointer even when it's NULL: >>> >>> ``` >>> bt->act_mask = value; // bt can still be NULL here >>> ``` >>> >>> Added a reassignment into the NULL check block to fix the issue. >>> >>> Fixes: c780e86dd48 ("blktrace: Protect q->blk_trace with RCU") >>> >>> Signed-off-by: Cengiz Can <cengiz@xxxxxxxxxx> >>> --- >>> Huge thanks goes to Steven Rostedt for his assistance. >>> >>> kernel/trace/blktrace.c | 4 +++- >>> 1 file changed, 3 insertions(+), 1 deletion(-) >>> >>> diff --git a/kernel/trace/blktrace.c b/kernel/trace/blktrace.c >>> index 4560878f0bac..29ea88f10b87 100644 >>> --- a/kernel/trace/blktrace.c >>> +++ b/kernel/trace/blktrace.c >>> @@ -1896,8 +1896,10 @@ static ssize_t sysfs_blk_trace_attr_store(struct device *dev, >>> } >>> >>> ret = 0; >>> - if (bt == NULL) >>> + if (bt == NULL) { >>> ret = blk_trace_setup_queue(q, bdev); >>> + bt = q->blk_trace; >> >> The return value 'ret' should be judged, it's wrong to set 'bt' if blk_trace_setup_queue() >> return failure. > > Why? If ret is an error, q is still valid, and bt would just be garbage. bt > is ignored below if ret is anything but zero. Why add an unnecessary if > condition here? > Oh..yes. You are right, sorry for missed the if (ret == 0) below. Reviewed-by: Bob Liu <bob.liu@xxxxxxxxxx> > That said, the bt assignment still needs rcu annotation: > > bt = rcu_dereference_protected(q->blk_trace, > lockdep_is_held(&q->blk_trace_mutex)); > > -- Steve > > >> >>> + } >>> >>> if (ret == 0) { >>> if (attr == &dev_attr_act_mask) >>> -- >>> 2.25.1 >>> >