Skip to content

Commit 0ef5b09

Browse files
axboegregkh
authored andcommitted
blktrace: fix unlocked access to init/start-stop/teardown
commit 1f2cac1 upstream. sg.c calls into the blktrace functions without holding the proper queue mutex for doing setup, start/stop, or teardown. Add internal unlocked variants, and export the ones that do the proper locking. Fixes: 6da127a ("blktrace: Add blktrace ioctls to SCSI generic devices") Tested-by: Dmitry Vyukov <[email protected]> Signed-off-by: Jens Axboe <[email protected]> Signed-off-by: Ben Hutchings <[email protected]> Signed-off-by: Sasha Levin <[email protected]>
1 parent b488092 commit 0ef5b09

File tree

1 file changed

+48
-10
lines changed

1 file changed

+48
-10
lines changed

kernel/trace/blktrace.c

Lines changed: 48 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -329,7 +329,7 @@ static void blk_trace_cleanup(struct blk_trace *bt)
329329
put_probe_ref();
330330
}
331331

332-
int blk_trace_remove(struct request_queue *q)
332+
static int __blk_trace_remove(struct request_queue *q)
333333
{
334334
struct blk_trace *bt;
335335

@@ -342,6 +342,17 @@ int blk_trace_remove(struct request_queue *q)
342342

343343
return 0;
344344
}
345+
346+
int blk_trace_remove(struct request_queue *q)
347+
{
348+
int ret;
349+
350+
mutex_lock(&q->blk_trace_mutex);
351+
ret = __blk_trace_remove(q);
352+
mutex_unlock(&q->blk_trace_mutex);
353+
354+
return ret;
355+
}
345356
EXPORT_SYMBOL_GPL(blk_trace_remove);
346357

347358
static ssize_t blk_dropped_read(struct file *filp, char __user *buffer,
@@ -546,9 +557,8 @@ int do_blk_trace_setup(struct request_queue *q, char *name, dev_t dev,
546557
return ret;
547558
}
548559

549-
int blk_trace_setup(struct request_queue *q, char *name, dev_t dev,
550-
struct block_device *bdev,
551-
char __user *arg)
560+
static int __blk_trace_setup(struct request_queue *q, char *name, dev_t dev,
561+
struct block_device *bdev, char __user *arg)
552562
{
553563
struct blk_user_trace_setup buts;
554564
int ret;
@@ -567,6 +577,19 @@ int blk_trace_setup(struct request_queue *q, char *name, dev_t dev,
567577
}
568578
return 0;
569579
}
580+
581+
int blk_trace_setup(struct request_queue *q, char *name, dev_t dev,
582+
struct block_device *bdev,
583+
char __user *arg)
584+
{
585+
int ret;
586+
587+
mutex_lock(&q->blk_trace_mutex);
588+
ret = __blk_trace_setup(q, name, dev, bdev, arg);
589+
mutex_unlock(&q->blk_trace_mutex);
590+
591+
return ret;
592+
}
570593
EXPORT_SYMBOL_GPL(blk_trace_setup);
571594

572595
#if defined(CONFIG_COMPAT) && defined(CONFIG_X86_64)
@@ -603,7 +626,7 @@ static int compat_blk_trace_setup(struct request_queue *q, char *name,
603626
}
604627
#endif
605628

606-
int blk_trace_startstop(struct request_queue *q, int start)
629+
static int __blk_trace_startstop(struct request_queue *q, int start)
607630
{
608631
int ret;
609632
struct blk_trace *bt = q->blk_trace;
@@ -642,6 +665,17 @@ int blk_trace_startstop(struct request_queue *q, int start)
642665

643666
return ret;
644667
}
668+
669+
int blk_trace_startstop(struct request_queue *q, int start)
670+
{
671+
int ret;
672+
673+
mutex_lock(&q->blk_trace_mutex);
674+
ret = __blk_trace_startstop(q, start);
675+
mutex_unlock(&q->blk_trace_mutex);
676+
677+
return ret;
678+
}
645679
EXPORT_SYMBOL_GPL(blk_trace_startstop);
646680

647681
/*
@@ -672,7 +706,7 @@ int blk_trace_ioctl(struct block_device *bdev, unsigned cmd, char __user *arg)
672706
switch (cmd) {
673707
case BLKTRACESETUP:
674708
bdevname(bdev, b);
675-
ret = blk_trace_setup(q, b, bdev->bd_dev, bdev, arg);
709+
ret = __blk_trace_setup(q, b, bdev->bd_dev, bdev, arg);
676710
break;
677711
#if defined(CONFIG_COMPAT) && defined(CONFIG_X86_64)
678712
case BLKTRACESETUP32:
@@ -683,10 +717,10 @@ int blk_trace_ioctl(struct block_device *bdev, unsigned cmd, char __user *arg)
683717
case BLKTRACESTART:
684718
start = 1;
685719
case BLKTRACESTOP:
686-
ret = blk_trace_startstop(q, start);
720+
ret = __blk_trace_startstop(q, start);
687721
break;
688722
case BLKTRACETEARDOWN:
689-
ret = blk_trace_remove(q);
723+
ret = __blk_trace_remove(q);
690724
break;
691725
default:
692726
ret = -ENOTTY;
@@ -704,10 +738,14 @@ int blk_trace_ioctl(struct block_device *bdev, unsigned cmd, char __user *arg)
704738
**/
705739
void blk_trace_shutdown(struct request_queue *q)
706740
{
741+
mutex_lock(&q->blk_trace_mutex);
742+
707743
if (q->blk_trace) {
708-
blk_trace_startstop(q, 0);
709-
blk_trace_remove(q);
744+
__blk_trace_startstop(q, 0);
745+
__blk_trace_remove(q);
710746
}
747+
748+
mutex_unlock(&q->blk_trace_mutex);
711749
}
712750

713751
/*

0 commit comments

Comments
 (0)