Commit 11eff663 authored by Jens Axboe's avatar Jens Axboe Committed by Marcelo Henrique Cerri

blktrace: fix unlocked access to init/start-stop/teardown

BugLink: https://bugs.launchpad.net/bugs/1881356

commit 1f2cac10 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: 6da127ad ("blktrace: Add blktrace ioctls to SCSI generic devices")
Tested-by: default avatarDmitry Vyukov <dvyukov@google.com>
Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
Signed-off-by: default avatarBen Hutchings <ben.hutchings@codethink.co.uk>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: default avatarIan May <ian.may@canonical.com>
Signed-off-by: default avatarKelsey Skunberg <kelsey.skunberg@canonical.com>
parent 9b8d43ac
......@@ -324,7 +324,7 @@ static void blk_trace_cleanup(struct blk_trace *bt)
put_probe_ref();
}
int blk_trace_remove(struct request_queue *q)
static int __blk_trace_remove(struct request_queue *q)
{
struct blk_trace *bt;
......@@ -337,6 +337,17 @@ int blk_trace_remove(struct request_queue *q)
return 0;
}
int blk_trace_remove(struct request_queue *q)
{
int ret;
mutex_lock(&q->blk_trace_mutex);
ret = __blk_trace_remove(q);
mutex_unlock(&q->blk_trace_mutex);
return ret;
}
EXPORT_SYMBOL_GPL(blk_trace_remove);
static ssize_t blk_dropped_read(struct file *filp, char __user *buffer,
......@@ -547,9 +558,8 @@ int do_blk_trace_setup(struct request_queue *q, char *name, dev_t dev,
return ret;
}
int blk_trace_setup(struct request_queue *q, char *name, dev_t dev,
struct block_device *bdev,
char __user *arg)
static int __blk_trace_setup(struct request_queue *q, char *name, dev_t dev,
struct block_device *bdev, char __user *arg)
{
struct blk_user_trace_setup buts;
int ret;
......@@ -568,6 +578,19 @@ int blk_trace_setup(struct request_queue *q, char *name, dev_t dev,
}
return 0;
}
int blk_trace_setup(struct request_queue *q, char *name, dev_t dev,
struct block_device *bdev,
char __user *arg)
{
int ret;
mutex_lock(&q->blk_trace_mutex);
ret = __blk_trace_setup(q, name, dev, bdev, arg);
mutex_unlock(&q->blk_trace_mutex);
return ret;
}
EXPORT_SYMBOL_GPL(blk_trace_setup);
#if defined(CONFIG_COMPAT) && defined(CONFIG_X86_64)
......@@ -604,7 +627,7 @@ static int compat_blk_trace_setup(struct request_queue *q, char *name,
}
#endif
int blk_trace_startstop(struct request_queue *q, int start)
int __blk_trace_startstop(struct request_queue *q, int start)
{
int ret;
struct blk_trace *bt;
......@@ -645,6 +668,17 @@ int blk_trace_startstop(struct request_queue *q, int start)
return ret;
}
int blk_trace_startstop(struct request_queue *q, int start)
{
int ret;
mutex_lock(&q->blk_trace_mutex);
ret = __blk_trace_startstop(q, start);
mutex_unlock(&q->blk_trace_mutex);
return ret;
}
EXPORT_SYMBOL_GPL(blk_trace_startstop);
/*
......@@ -675,7 +709,7 @@ int blk_trace_ioctl(struct block_device *bdev, unsigned cmd, char __user *arg)
switch (cmd) {
case BLKTRACESETUP:
bdevname(bdev, b);
ret = blk_trace_setup(q, b, bdev->bd_dev, bdev, arg);
ret = __blk_trace_setup(q, b, bdev->bd_dev, bdev, arg);
break;
#if defined(CONFIG_COMPAT) && defined(CONFIG_X86_64)
case BLKTRACESETUP32:
......@@ -686,10 +720,10 @@ int blk_trace_ioctl(struct block_device *bdev, unsigned cmd, char __user *arg)
case BLKTRACESTART:
start = 1;
case BLKTRACESTOP:
ret = blk_trace_startstop(q, start);
ret = __blk_trace_startstop(q, start);
break;
case BLKTRACETEARDOWN:
ret = blk_trace_remove(q);
ret = __blk_trace_remove(q);
break;
default:
ret = -ENOTTY;
......@@ -707,11 +741,15 @@ int blk_trace_ioctl(struct block_device *bdev, unsigned cmd, char __user *arg)
**/
void blk_trace_shutdown(struct request_queue *q)
{
mutex_lock(&q->blk_trace_mutex);
if (rcu_dereference_protected(q->blk_trace,
lockdep_is_held(&q->blk_trace_mutex))) {
blk_trace_startstop(q, 0);
blk_trace_remove(q);
__blk_trace_startstop(q, 0);
__blk_trace_remove(q);
}
mutex_unlock(&q->blk_trace_mutex);
}
/*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment