From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
To: linux-kernel@vger.kernel.org
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
stable@vger.kernel.org,
syzbot+4349872271ece473a7c91190b68b4bac7c5dbc87@syzkaller.appspotmail.com,
syzbot+40bd32c4d9a3cc12a339@syzkaller.appspotmail.com,
syzbot+769c54e66f994b041be7@syzkaller.appspotmail.com,
syzbot+0a89a9ce473936c57065@syzkaller.appspotmail.com,
Theodore Tso <tytso@mit.edu>, Jens Axboe <axboe@kernel.dk>
Subject: [PATCH 3.18 09/29] loop: add recursion validation to LOOP_CHANGE_FD
Date: Fri, 20 Jul 2018 14:11:04 +0200 [thread overview]
Message-ID: <20180720115159.309929348@linuxfoundation.org> (raw)
In-Reply-To: <20180720115158.974693829@linuxfoundation.org>
3.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Theodore Ts'o <tytso@mit.edu>
commit d2ac838e4cd7e5e9891ecc094d626734b0245c99 upstream.
Refactor the validation code used in LOOP_SET_FD so it is also used in
LOOP_CHANGE_FD. Otherwise it is possible to construct a set of loop
devices that all refer to each other. This can lead to a infinite
loop in starting with "while (is_loop_device(f)) .." in loop_set_fd().
Fix this by refactoring out the validation code and using it for
LOOP_CHANGE_FD as well as LOOP_SET_FD.
Reported-by: syzbot+4349872271ece473a7c91190b68b4bac7c5dbc87@syzkaller.appspotmail.com
Reported-by: syzbot+40bd32c4d9a3cc12a339@syzkaller.appspotmail.com
Reported-by: syzbot+769c54e66f994b041be7@syzkaller.appspotmail.com
Reported-by: syzbot+0a89a9ce473936c57065@syzkaller.appspotmail.com
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/block/loop.c | 68 ++++++++++++++++++++++++++++-----------------------
1 file changed, 38 insertions(+), 30 deletions(-)
--- a/drivers/block/loop.c
+++ b/drivers/block/loop.c
@@ -628,6 +628,36 @@ out:
}
+static inline int is_loop_device(struct file *file)
+{
+ struct inode *i = file->f_mapping->host;
+
+ return i && S_ISBLK(i->i_mode) && MAJOR(i->i_rdev) == LOOP_MAJOR;
+}
+
+static int loop_validate_file(struct file *file, struct block_device *bdev)
+{
+ struct inode *inode = file->f_mapping->host;
+ struct file *f = file;
+
+ /* Avoid recursion */
+ while (is_loop_device(f)) {
+ struct loop_device *l;
+
+ if (f->f_mapping->host->i_bdev == bdev)
+ return -EBADF;
+
+ l = f->f_mapping->host->i_bdev->bd_disk->private_data;
+ if (l->lo_state == Lo_unbound) {
+ return -EINVAL;
+ }
+ f = l->lo_backing_file;
+ }
+ if (!S_ISREG(inode->i_mode) && !S_ISBLK(inode->i_mode))
+ return -EINVAL;
+ return 0;
+}
+
/*
* loop_change_fd switched the backing store of a loopback device to
* a new file. This is useful for operating system installers to free up
@@ -657,14 +687,15 @@ static int loop_change_fd(struct loop_de
if (!file)
goto out;
+ error = loop_validate_file(file, bdev);
+ if (error)
+ goto out_putf;
+
inode = file->f_mapping->host;
old_file = lo->lo_backing_file;
error = -EINVAL;
- if (!S_ISREG(inode->i_mode) && !S_ISBLK(inode->i_mode))
- goto out_putf;
-
/* size of the new backing store needs to be the same */
if (get_loop_size(lo, file) != get_loop_size(lo, old_file))
goto out_putf;
@@ -685,13 +716,6 @@ static int loop_change_fd(struct loop_de
return error;
}
-static inline int is_loop_device(struct file *file)
-{
- struct inode *i = file->f_mapping->host;
-
- return i && S_ISBLK(i->i_mode) && MAJOR(i->i_rdev) == LOOP_MAJOR;
-}
-
/* loop sysfs attributes */
static ssize_t loop_attr_show(struct device *dev, char *page,
@@ -823,7 +847,7 @@ static void loop_config_discard(struct l
static int loop_set_fd(struct loop_device *lo, fmode_t mode,
struct block_device *bdev, unsigned int arg)
{
- struct file *file, *f;
+ struct file *file;
struct inode *inode;
struct address_space *mapping;
unsigned lo_blocksize;
@@ -843,29 +867,13 @@ static int loop_set_fd(struct loop_devic
if (lo->lo_state != Lo_unbound)
goto out_putf;
- /* Avoid recursion */
- f = file;
- while (is_loop_device(f)) {
- struct loop_device *l;
-
- if (f->f_mapping->host->i_bdev == bdev)
- goto out_putf;
-
- l = f->f_mapping->host->i_bdev->bd_disk->private_data;
- if (l->lo_state == Lo_unbound) {
- error = -EINVAL;
- goto out_putf;
- }
- f = l->lo_backing_file;
- }
+ error = loop_validate_file(file, bdev);
+ if (error)
+ goto out_putf;
mapping = file->f_mapping;
inode = mapping->host;
- error = -EINVAL;
- if (!S_ISREG(inode->i_mode) && !S_ISBLK(inode->i_mode))
- goto out_putf;
-
if (!(file->f_mode & FMODE_WRITE) || !(mode & FMODE_WRITE) ||
!file->f_op->write)
lo_flags |= LO_FLAGS_READ_ONLY;
next prev parent reply other threads:[~2018-07-20 12:26 UTC|newest]
Thread overview: 34+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-07-20 12:10 [PATCH 3.18 00/29] 3.18.116-stable review Greg Kroah-Hartman
2018-07-20 12:10 ` [PATCH 3.18 01/29] ibmasm: dont write out of bounds in read handler Greg Kroah-Hartman
2018-07-20 12:10 ` [PATCH 3.18 02/29] USB: serial: keyspan_pda: fix modem-status error handling Greg Kroah-Hartman
2018-07-20 12:10 ` [PATCH 3.18 03/29] USB: yurex: fix out-of-bounds uaccess in read handler Greg Kroah-Hartman
2018-07-20 12:10 ` [PATCH 3.18 04/29] USB: serial: mos7840: fix status-register error handling Greg Kroah-Hartman
2018-07-20 12:11 ` [PATCH 3.18 05/29] usb: quirks: add delay quirks for Corsair Strafe Greg Kroah-Hartman
2018-07-20 12:11 ` [PATCH 3.18 06/29] xhci: xhci-mem: off by one in xhci_stream_id_to_ring() Greg Kroah-Hartman
2018-07-20 12:11 ` [PATCH 3.18 07/29] Fix up non-directory creation in SGID directories Greg Kroah-Hartman
2018-07-20 12:11 ` [PATCH 3.18 08/29] netfilter: x_tables: initialise match/target check parameter struct Greg Kroah-Hartman
2018-07-20 12:11 ` Greg Kroah-Hartman [this message]
2018-07-20 12:11 ` [PATCH 3.18 10/29] PM / hibernate: Fix oops at snapshot_write() Greg Kroah-Hartman
2018-07-20 12:11 ` [PATCH 3.18 11/29] RDMA/ucm: Mark UCM interface as BROKEN Greg Kroah-Hartman
2018-07-20 12:11 ` [PATCH 3.18 12/29] loop: remember whether sysfs_create_group() was done Greg Kroah-Hartman
2018-07-20 12:11 ` [PATCH 3.18 13/29] bcm63xx_enet: correct clock usage Greg Kroah-Hartman
2018-07-20 12:11 ` [PATCH 3.18 14/29] bcm63xx_enet: do not write to random DMA channel on BCM6345 Greg Kroah-Hartman
2018-07-20 12:11 ` [PATCH 3.18 15/29] crypto: crypto4xx - remove bad list_del Greg Kroah-Hartman
2018-07-20 12:11 ` [PATCH 3.18 16/29] crypto: crypto4xx - fix crypto4xx_build_pdr, crypto4xx_build_sdr leak Greg Kroah-Hartman
2018-07-20 12:11 ` [PATCH 3.18 19/29] net/mlx5: Fix incorrect raw command length parsing Greg Kroah-Hartman
2018-07-20 12:11 ` [PATCH 3.18 20/29] net: sungem: fix rx checksum support Greg Kroah-Hartman
2018-07-20 12:11 ` [PATCH 3.18 21/29] tcp: fix Fast Open key endianness Greg Kroah-Hartman
2018-07-20 12:11 ` [PATCH 3.18 23/29] vhost_net: validate sock before trying to put its fd Greg Kroah-Hartman
2018-07-20 12:11 ` [PATCH 3.18 24/29] net_sched: blackhole: tell upper qdisc about dropped packets Greg Kroah-Hartman
2018-07-20 12:11 ` [PATCH 3.18 25/29] net/mlx5: Fix command interface race in polling mode Greg Kroah-Hartman
2018-07-20 12:11 ` [PATCH 3.18 26/29] netfilter: ebtables: reject non-bridge targets Greg Kroah-Hartman
2018-07-20 12:11 ` [PATCH 3.18 27/29] KEYS: DNS: fix parsing multiple options Greg Kroah-Hartman
2018-07-20 12:11 ` [PATCH 3.18 28/29] rds: avoid unenecessary cong_update in loop transport Greg Kroah-Hartman
2018-07-20 12:11 ` [PATCH 3.18 29/29] net/nfc: Avoid stalls when nfc_alloc_send_skb() returned NULL Greg Kroah-Hartman
2018-07-20 13:33 ` [PATCH 3.18 00/29] 3.18.116-stable review Nathan Chancellor
2018-07-21 13:38 ` Guenter Roeck
2018-07-22 11:42 ` Greg Kroah-Hartman
-- strict thread matches above, loose matches on Subject: below --
2018-07-20 12:11 [PATCH 3.18 17/29] net: dccp: avoid crash in ccid3_hc_rx_send_feedback() Greg Kroah-Hartman
2018-07-20 12:11 ` Greg Kroah-Hartman
2018-07-20 12:11 [PATCH 3.18 18/29] net: dccp: switch rx_tstamp_last_feedback to monotonic clock Greg Kroah-Hartman
2018-07-20 12:11 ` Greg Kroah-Hartman
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=20180720115159.309929348@linuxfoundation.org \
--to=gregkh@linuxfoundation.org \
--cc=axboe@kernel.dk \
--cc=linux-kernel@vger.kernel.org \
--cc=stable@vger.kernel.org \
--cc=syzbot+0a89a9ce473936c57065@syzkaller.appspotmail.com \
--cc=syzbot+40bd32c4d9a3cc12a339@syzkaller.appspotmail.com \
--cc=syzbot+4349872271ece473a7c91190b68b4bac7c5dbc87@syzkaller.appspotmail.com \
--cc=syzbot+769c54e66f994b041be7@syzkaller.appspotmail.com \
--cc=tytso@mit.edu \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.