From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
To: linux-kernel@vger.kernel.org
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
stable@vger.kernel.org,
Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>,
syzbot <syzbot+bf89c128e05dd6c62523@syzkaller.appspotmail.com>,
Jan Kara <jack@suse.cz>, Jens Axboe <axboe@kernel.dk>
Subject: [PATCH 4.9 46/51] block/loop: Use global lock for ioctl() operation.
Date: Mon, 21 Jan 2019 14:44:42 +0100 [thread overview]
Message-ID: <20190121122458.314380962@linuxfoundation.org> (raw)
In-Reply-To: <20190121122453.700446926@linuxfoundation.org>
4.9-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
commit 310ca162d779efee8a2dc3731439680f3e9c1e86 upstream.
syzbot is reporting NULL pointer dereference [1] which is caused by
race condition between ioctl(loop_fd, LOOP_CLR_FD, 0) versus
ioctl(other_loop_fd, LOOP_SET_FD, loop_fd) due to traversing other
loop devices at loop_validate_file() without holding corresponding
lo->lo_ctl_mutex locks.
Since ioctl() request on loop devices is not frequent operation, we don't
need fine grained locking. Let's use global lock in order to allow safe
traversal at loop_validate_file().
Note that syzbot is also reporting circular locking dependency between
bdev->bd_mutex and lo->lo_ctl_mutex [2] which is caused by calling
blkdev_reread_part() with lock held. This patch does not address it.
[1] https://syzkaller.appspot.com/bug?id=f3cfe26e785d85f9ee259f385515291d21bd80a3
[2] https://syzkaller.appspot.com/bug?id=bf154052f0eea4bc7712499e4569505907d15889
Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
Reported-by: syzbot <syzbot+bf89c128e05dd6c62523@syzkaller.appspotmail.com>
Reviewed-by: Jan Kara <jack@suse.cz>
Signed-off-by: Jan Kara <jack@suse.cz>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/block/loop.c | 42 +++++++++++++++++++++---------------------
drivers/block/loop.h | 1 -
2 files changed, 21 insertions(+), 22 deletions(-)
--- a/drivers/block/loop.c
+++ b/drivers/block/loop.c
@@ -82,6 +82,7 @@
static DEFINE_IDR(loop_index_idr);
static DEFINE_MUTEX(loop_index_mutex);
+static DEFINE_MUTEX(loop_ctl_mutex);
static int max_part;
static int part_shift;
@@ -1033,7 +1034,7 @@ static int loop_clr_fd(struct loop_devic
*/
if (atomic_read(&lo->lo_refcnt) > 1) {
lo->lo_flags |= LO_FLAGS_AUTOCLEAR;
- mutex_unlock(&lo->lo_ctl_mutex);
+ mutex_unlock(&loop_ctl_mutex);
return 0;
}
@@ -1082,12 +1083,12 @@ static int loop_clr_fd(struct loop_devic
if (!part_shift)
lo->lo_disk->flags |= GENHD_FL_NO_PART_SCAN;
loop_unprepare_queue(lo);
- mutex_unlock(&lo->lo_ctl_mutex);
+ mutex_unlock(&loop_ctl_mutex);
/*
- * Need not hold lo_ctl_mutex to fput backing file.
- * Calling fput holding lo_ctl_mutex triggers a circular
+ * Need not hold loop_ctl_mutex to fput backing file.
+ * Calling fput holding loop_ctl_mutex triggers a circular
* lock dependency possibility warning as fput can take
- * bd_mutex which is usually taken before lo_ctl_mutex.
+ * bd_mutex which is usually taken before loop_ctl_mutex.
*/
fput(filp);
return 0;
@@ -1350,7 +1351,7 @@ static int lo_ioctl(struct block_device
struct loop_device *lo = bdev->bd_disk->private_data;
int err;
- mutex_lock_nested(&lo->lo_ctl_mutex, 1);
+ mutex_lock_nested(&loop_ctl_mutex, 1);
switch (cmd) {
case LOOP_SET_FD:
err = loop_set_fd(lo, mode, bdev, arg);
@@ -1359,7 +1360,7 @@ static int lo_ioctl(struct block_device
err = loop_change_fd(lo, bdev, arg);
break;
case LOOP_CLR_FD:
- /* loop_clr_fd would have unlocked lo_ctl_mutex on success */
+ /* loop_clr_fd would have unlocked loop_ctl_mutex on success */
err = loop_clr_fd(lo);
if (!err)
goto out_unlocked;
@@ -1395,7 +1396,7 @@ static int lo_ioctl(struct block_device
default:
err = lo->ioctl ? lo->ioctl(lo, cmd, arg) : -EINVAL;
}
- mutex_unlock(&lo->lo_ctl_mutex);
+ mutex_unlock(&loop_ctl_mutex);
out_unlocked:
return err;
@@ -1528,16 +1529,16 @@ static int lo_compat_ioctl(struct block_
switch(cmd) {
case LOOP_SET_STATUS:
- mutex_lock(&lo->lo_ctl_mutex);
+ mutex_lock(&loop_ctl_mutex);
err = loop_set_status_compat(
lo, (const struct compat_loop_info __user *) arg);
- mutex_unlock(&lo->lo_ctl_mutex);
+ mutex_unlock(&loop_ctl_mutex);
break;
case LOOP_GET_STATUS:
- mutex_lock(&lo->lo_ctl_mutex);
+ mutex_lock(&loop_ctl_mutex);
err = loop_get_status_compat(
lo, (struct compat_loop_info __user *) arg);
- mutex_unlock(&lo->lo_ctl_mutex);
+ mutex_unlock(&loop_ctl_mutex);
break;
case LOOP_SET_CAPACITY:
case LOOP_CLR_FD:
@@ -1581,7 +1582,7 @@ static void __lo_release(struct loop_dev
if (atomic_dec_return(&lo->lo_refcnt))
return;
- mutex_lock(&lo->lo_ctl_mutex);
+ mutex_lock(&loop_ctl_mutex);
if (lo->lo_flags & LO_FLAGS_AUTOCLEAR) {
/*
* In autoclear mode, stop the loop thread
@@ -1598,7 +1599,7 @@ static void __lo_release(struct loop_dev
loop_flush(lo);
}
- mutex_unlock(&lo->lo_ctl_mutex);
+ mutex_unlock(&loop_ctl_mutex);
}
static void lo_release(struct gendisk *disk, fmode_t mode)
@@ -1644,10 +1645,10 @@ static int unregister_transfer_cb(int id
struct loop_device *lo = ptr;
struct loop_func_table *xfer = data;
- mutex_lock(&lo->lo_ctl_mutex);
+ mutex_lock(&loop_ctl_mutex);
if (lo->lo_encryption == xfer)
loop_release_xfer(lo);
- mutex_unlock(&lo->lo_ctl_mutex);
+ mutex_unlock(&loop_ctl_mutex);
return 0;
}
@@ -1813,7 +1814,6 @@ static int loop_add(struct loop_device *
if (!part_shift)
disk->flags |= GENHD_FL_NO_PART_SCAN;
disk->flags |= GENHD_FL_EXT_DEVT;
- mutex_init(&lo->lo_ctl_mutex);
atomic_set(&lo->lo_refcnt, 0);
lo->lo_number = i;
spin_lock_init(&lo->lo_lock);
@@ -1926,19 +1926,19 @@ static long loop_control_ioctl(struct fi
ret = loop_lookup(&lo, parm);
if (ret < 0)
break;
- mutex_lock(&lo->lo_ctl_mutex);
+ mutex_lock(&loop_ctl_mutex);
if (lo->lo_state != Lo_unbound) {
ret = -EBUSY;
- mutex_unlock(&lo->lo_ctl_mutex);
+ mutex_unlock(&loop_ctl_mutex);
break;
}
if (atomic_read(&lo->lo_refcnt) > 0) {
ret = -EBUSY;
- mutex_unlock(&lo->lo_ctl_mutex);
+ mutex_unlock(&loop_ctl_mutex);
break;
}
lo->lo_disk->private_data = NULL;
- mutex_unlock(&lo->lo_ctl_mutex);
+ mutex_unlock(&loop_ctl_mutex);
idr_remove(&loop_index_idr, lo->lo_number);
loop_remove(lo);
break;
--- a/drivers/block/loop.h
+++ b/drivers/block/loop.h
@@ -55,7 +55,6 @@ struct loop_device {
spinlock_t lo_lock;
int lo_state;
- struct mutex lo_ctl_mutex;
struct kthread_worker worker;
struct task_struct *worker_task;
bool use_dio;
next prev parent reply other threads:[~2019-01-21 13:56 UTC|newest]
Thread overview: 56+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-01-21 13:43 [PATCH 4.9 00/51] 4.9.152-stable review Greg Kroah-Hartman
2019-01-21 13:43 ` [PATCH 4.9 01/51] tty/ldsem: Wake up readers after timed out down_write() Greg Kroah-Hartman
2019-01-21 13:43 ` [PATCH 4.9 02/51] tty: Hold tty_ldisc_lock() during tty_reopen() Greg Kroah-Hartman
2019-01-21 13:43 ` [PATCH 4.9 03/51] tty: Simplify tty->count math in tty_reopen() Greg Kroah-Hartman
2019-01-21 13:44 ` [PATCH 4.9 04/51] tty: Dont hold ldisc lock in tty_reopen() if ldisc present Greg Kroah-Hartman
2019-01-21 13:44 ` [PATCH 4.9 05/51] can: gw: ensure DLC boundaries after CAN frame modification Greg Kroah-Hartman
2019-01-21 13:44 ` [PATCH 4.9 06/51] Revert "f2fs: do not recover from previous remained wrong dnodes" Greg Kroah-Hartman
2019-01-21 13:44 ` [PATCH 4.9 07/51] media: em28xx: Fix misplaced reset of dev->v4l::field_count Greg Kroah-Hartman
2019-01-21 13:44 ` [PATCH 4.9 08/51] proc: Remove empty line in /proc/self/status Greg Kroah-Hartman
2019-01-21 13:44 ` [PATCH 4.9 09/51] Revert "scsi: target: iscsi: cxgbit: fix csk leak" Greg Kroah-Hartman
2019-01-21 13:44 ` [PATCH 4.9 10/51] scsi: target: iscsi: cxgbit: fix csk leak Greg Kroah-Hartman
2019-01-21 13:44 ` [PATCH 4.9 11/51] arm64/kvm: consistently handle host HCR_EL2 flags Greg Kroah-Hartman
2019-01-21 13:44 ` [PATCH 4.9 12/51] arm64: Dont trap host pointer auth use to EL2 Greg Kroah-Hartman
2019-01-21 13:44 ` [PATCH 4.9 13/51] ipv6: fix kernel-infoleak in ipv6_local_error() Greg Kroah-Hartman
2019-01-21 13:44 ` [PATCH 4.9 14/51] net: bridge: fix a bug on using a neighbour cache entry without checking its state Greg Kroah-Hartman
2019-01-21 13:44 ` [PATCH 4.9 15/51] packet: Do not leak dev refcounts on error exit Greg Kroah-Hartman
2019-01-21 13:44 ` [PATCH 4.9 16/51] bonding: update nest level on unlink Greg Kroah-Hartman
2019-01-21 13:44 ` [PATCH 4.9 17/51] ip: on queued skb use skb_header_pointer instead of pskb_may_pull Greg Kroah-Hartman
2019-01-21 13:44 ` [PATCH 4.9 18/51] crypto: caam - fix zero-length buffer DMA mapping Greg Kroah-Hartman
2019-01-21 13:44 ` [PATCH 4.9 19/51] crypto: authencesn - Avoid twice completion call in decrypt path Greg Kroah-Hartman
2019-01-21 13:44 ` [PATCH 4.9 20/51] crypto: authenc - fix parsing key with misaligned rta_len Greg Kroah-Hartman
2019-01-21 13:44 ` [PATCH 4.9 21/51] btrfs: wait on ordered extents on abort cleanup Greg Kroah-Hartman
2019-01-21 13:44 ` [PATCH 4.9 22/51] Yama: Check for pid death before checking ancestry Greg Kroah-Hartman
2019-01-21 13:44 ` [PATCH 4.9 23/51] scsi: core: Synchronize request queue PM status only on successful resume Greg Kroah-Hartman
2019-01-21 13:44 ` [PATCH 4.9 24/51] scsi: sd: Fix cache_type_store() Greg Kroah-Hartman
2019-01-21 13:44 ` [PATCH 4.9 25/51] crypto: talitos - reorder code in talitos_edesc_alloc() Greg Kroah-Hartman
2019-01-21 13:44 ` [PATCH 4.9 26/51] crypto: talitos - fix ablkcipher for CONFIG_VMAP_STACK Greg Kroah-Hartman
2019-01-21 13:44 ` [PATCH 4.9 27/51] mips: fix n32 compat_ipc_parse_version Greg Kroah-Hartman
2019-01-21 13:44 ` [PATCH 4.9 28/51] mfd: tps6586x: Handle interrupts on suspend Greg Kroah-Hartman
2019-01-21 13:44 ` [PATCH 4.9 29/51] arm64: kaslr: ensure randomized quantities are clean to the PoC Greg Kroah-Hartman
2019-01-21 13:44 ` [PATCH 4.9 30/51] Disable MSI also when pcie-octeon.pcie_disable on Greg Kroah-Hartman
2019-01-21 13:44 ` [PATCH 4.9 31/51] omap2fb: Fix stack memory disclosure Greg Kroah-Hartman
2019-01-21 13:44 ` [PATCH 4.9 32/51] media: vivid: fix error handling of kthread_run Greg Kroah-Hartman
2019-01-21 13:44 ` [PATCH 4.9 33/51] media: vivid: set min width/height to a value > 0 Greg Kroah-Hartman
2019-01-21 13:44 ` [PATCH 4.9 34/51] LSM: Check for NULL cred-security on free Greg Kroah-Hartman
2019-01-21 13:44 ` [PATCH 4.9 35/51] media: vb2: vb2_mmap: move lock up Greg Kroah-Hartman
2019-01-21 13:44 ` [PATCH 4.9 36/51] sunrpc: handle ENOMEM in rpcb_getport_async Greg Kroah-Hartman
2019-01-21 13:44 ` [PATCH 4.9 37/51] netfilter: ebtables: account ebt_table_info to kmemcg Greg Kroah-Hartman
2019-01-21 13:44 ` [PATCH 4.9 38/51] selinux: fix GPF on invalid policy Greg Kroah-Hartman
2019-01-21 13:44 ` [PATCH 4.9 39/51] blockdev: Fix livelocks on loop device Greg Kroah-Hartman
2019-01-21 13:44 ` [PATCH 4.9 40/51] sctp: allocate sctp_sockaddr_entry with kzalloc Greg Kroah-Hartman
2019-01-21 13:44 ` [PATCH 4.9 41/51] tipc: fix uninit-value in tipc_nl_compat_link_reset_stats Greg Kroah-Hartman
2019-01-21 13:44 ` [PATCH 4.9 42/51] tipc: fix uninit-value in tipc_nl_compat_bearer_enable Greg Kroah-Hartman
2019-01-21 13:44 ` [PATCH 4.9 43/51] tipc: fix uninit-value in tipc_nl_compat_link_set Greg Kroah-Hartman
2019-01-21 13:44 ` [PATCH 4.9 44/51] tipc: fix uninit-value in tipc_nl_compat_name_table_dump Greg Kroah-Hartman
2019-01-21 13:44 ` [PATCH 4.9 45/51] tipc: fix uninit-value in tipc_nl_compat_doit Greg Kroah-Hartman
2019-01-21 13:44 ` Greg Kroah-Hartman [this message]
2019-01-21 13:44 ` [PATCH 4.9 47/51] loop: Fold __loop_release into loop_release Greg Kroah-Hartman
2019-01-21 13:44 ` [PATCH 4.9 48/51] loop: Get rid of loop_index_mutex Greg Kroah-Hartman
2019-01-21 13:44 ` [PATCH 4.9 49/51] loop: Fix double mutex_unlock(&loop_ctl_mutex) in loop_control_ioctl() Greg Kroah-Hartman
2019-01-21 13:44 ` [PATCH 4.9 50/51] drm/fb-helper: Ignore the value of fb_var_screeninfo.pixclock Greg Kroah-Hartman
2019-01-21 13:44 ` [PATCH 4.9 51/51] mm, memcg: fix reclaim deadlock with writeback Greg Kroah-Hartman
2019-01-22 13:40 ` [PATCH 4.9 00/51] 4.9.152-stable review Naresh Kamboju
2019-01-22 20:44 ` Guenter Roeck
2019-01-22 22:39 ` shuah
2019-01-23 9:06 ` Jon Hunter
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20190121122458.314380962@linuxfoundation.org \
--to=gregkh@linuxfoundation.org \
--cc=axboe@kernel.dk \
--cc=jack@suse.cz \
--cc=linux-kernel@vger.kernel.org \
--cc=penguin-kernel@I-love.SAKURA.ne.jp \
--cc=stable@vger.kernel.org \
--cc=syzbot+bf89c128e05dd6c62523@syzkaller.appspotmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).