LKML Archive on lore.kernel.org
help / color / mirror / Atom feed
From: Greg KH <gregkh@suse.de>
To: linux-kernel@vger.kernel.org, stable@kernel.org,
Linus Torvalds <torvalds@linux-foundation.org>
Cc: Justin Forbes <jmforbes@linuxtx.org>,
Zwane Mwaikambo <zwane@arm.linux.org.uk>,
"Theodore Ts'o" <tytso@mit.edu>,
Randy Dunlap <rdunlap@xenotime.net>,
Dave Jones <davej@redhat.com>,
Chuck Wolber <chuckw@quantumlinux.com>,
Chris Wedgwood <reviews@ml.cw.f00f.org>,
Michael Krufky <mkrufky@linuxtv.org>,
Chuck Ebbert <cebbert@redhat.com>,
Domenico Andreoli <cavokz@gmail.com>,
akpm@linux-foundation.org, alan@lxorguk.ukuu.org.uk,
Junichi Nomura <j-nomura@ce.jp.nec.com>,
dm-devel@redhat.com, Alasdair G Kergon <agk@redhat.com>
Subject: [patch 02/73] dm: table detect io beyond device
Date: Wed, 6 Feb 2008 15:50:51 -0800 [thread overview]
Message-ID: <20080206235051.GC13121@suse.de> (raw)
In-Reply-To: <20080206235015.GA13121@suse.de>
[-- Attachment #1: dm-table-detect-io-beyond-device.patch --]
[-- Type: text/plain, Size: 5370 bytes --]
2.6.23-stable review patch. If anyone has any objections, please let us know.
------------------
From: Jun'ichi Nomura <j-nomura@ce.jp.nec.com>
Patch 512875bd9661368da6f993205a61213b79ba1df0 in mainline.
This patch fixes a panic on shrinking a DM device if there is
outstanding I/O to the part of the device that is being removed.
(Normally this doesn't happen - a filesystem would be resized first,
for example.)
The bug is that __clone_and_map() assumes dm_table_find_target()
always returns a valid pointer. It may fail if a bio arrives from the
block layer but its target sector is no longer included in the DM
btree.
This patch appends an empty entry to table->targets[] which will
be returned by a lookup beyond the end of the device.
After calling dm_table_find_target(), __clone_and_map() and target_message()
check for this condition using
dm_target_is_valid().
Sample test script to trigger oops:
#!/bin/bash
FILE=$(mktemp)
LODEV=$(losetup -f)
MAP=$(basename ${FILE})
SIZE=4M
dd if=/dev/zero of=${FILE} bs=${SIZE} count=1
losetup ${LODEV} ${FILE}
echo "0 $(blockdev --getsz ${LODEV}) linear ${LODEV} 0" |dmsetup create ${MAP}
dmsetup suspend ${MAP}
echo "0 1 linear ${LODEV} 0" |dmsetup load ${MAP}
dd if=/dev/zero of=/dev/mapper/${MAP} bs=${SIZE} count=1 &
echo "Wait til dd push some I/O"
sleep 5
dmsetup resume ${MAP}
Signed-off-by: Jun'ichi Nomura <j-nomura@ce.jp.nec.com>
Signed-off-by: Alasdair G Kergon <agk@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
drivers/md/dm-ioctl.c | 10 +++-------
drivers/md/dm-table.c | 7 ++++++-
drivers/md/dm.c | 24 ++++++++++++++++++------
drivers/md/dm.h | 5 +++++
4 files changed, 32 insertions(+), 14 deletions(-)
--- a/drivers/md/dm-ioctl.c
+++ b/drivers/md/dm-ioctl.c
@@ -1250,21 +1250,17 @@ static int target_message(struct dm_ioct
if (!table)
goto out_argv;
- if (tmsg->sector >= dm_table_get_size(table)) {
+ ti = dm_table_find_target(table, tmsg->sector);
+ if (!dm_target_is_valid(ti)) {
DMWARN("Target message sector outside device.");
r = -EINVAL;
- goto out_table;
- }
-
- ti = dm_table_find_target(table, tmsg->sector);
- if (ti->type->message)
+ } else if (ti->type->message)
r = ti->type->message(ti, argc, argv);
else {
DMWARN("Target type does not support messages");
r = -EINVAL;
}
- out_table:
dm_table_put(table);
out_argv:
kfree(argv);
--- a/drivers/md/dm-table.c
+++ b/drivers/md/dm-table.c
@@ -187,8 +187,10 @@ static int alloc_targets(struct dm_table
/*
* Allocate both the target array and offset array at once.
+ * Append an empty entry to catch sectors beyond the end of
+ * the device.
*/
- n_highs = (sector_t *) dm_vcalloc(num, sizeof(struct dm_target) +
+ n_highs = (sector_t *) dm_vcalloc(num + 1, sizeof(struct dm_target) +
sizeof(sector_t));
if (!n_highs)
return -ENOMEM;
@@ -862,6 +864,9 @@ struct dm_target *dm_table_get_target(st
/*
* Search the btree for the correct target.
+ *
+ * Caller should check returned pointer with dm_target_is_valid()
+ * to trap I/O beyond end of device.
*/
struct dm_target *dm_table_find_target(struct dm_table *t, sector_t sector)
{
--- a/drivers/md/dm.c
+++ b/drivers/md/dm.c
@@ -663,13 +663,19 @@ static struct bio *clone_bio(struct bio
return clone;
}
-static void __clone_and_map(struct clone_info *ci)
+static int __clone_and_map(struct clone_info *ci)
{
struct bio *clone, *bio = ci->bio;
- struct dm_target *ti = dm_table_find_target(ci->map, ci->sector);
- sector_t len = 0, max = max_io_len(ci->md, ci->sector, ti);
+ struct dm_target *ti;
+ sector_t len = 0, max;
struct dm_target_io *tio;
+ ti = dm_table_find_target(ci->map, ci->sector);
+ if (!dm_target_is_valid(ti))
+ return -EIO;
+
+ max = max_io_len(ci->md, ci->sector, ti);
+
/*
* Allocate a target io object.
*/
@@ -727,6 +733,9 @@ static void __clone_and_map(struct clone
do {
if (offset) {
ti = dm_table_find_target(ci->map, ci->sector);
+ if (!dm_target_is_valid(ti))
+ return -EIO;
+
max = max_io_len(ci->md, ci->sector, ti);
tio = alloc_tio(ci->md);
@@ -750,6 +759,8 @@ static void __clone_and_map(struct clone
ci->idx++;
}
+
+ return 0;
}
/*
@@ -758,6 +769,7 @@ static void __clone_and_map(struct clone
static void __split_bio(struct mapped_device *md, struct bio *bio)
{
struct clone_info ci;
+ int error = 0;
ci.map = dm_get_table(md);
if (!ci.map) {
@@ -777,11 +789,11 @@ static void __split_bio(struct mapped_de
ci.idx = bio->bi_idx;
start_io_acct(ci.io);
- while (ci.sector_count)
- __clone_and_map(&ci);
+ while (ci.sector_count && !error)
+ error = __clone_and_map(&ci);
/* drop the extra reference count */
- dec_pending(ci.io, 0);
+ dec_pending(ci.io, error);
dm_table_put(ci.map);
}
/*-----------------------------------------------------------------
--- a/drivers/md/dm.h
+++ b/drivers/md/dm.h
@@ -113,6 +113,11 @@ int dm_table_any_congested(struct dm_tab
void dm_table_unplug_all(struct dm_table *t);
int dm_table_flush_all(struct dm_table *t);
+/*
+ * To check the return value from dm_table_find_target().
+ */
+#define dm_target_is_valid(t) ((t)->table)
+
/*-----------------------------------------------------------------
* A registry of target types.
*---------------------------------------------------------------*/
--
next prev parent reply other threads:[~2008-02-06 23:54 UTC|newest]
Thread overview: 75+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <20080206234302.769849277@mini.kroah.org>
2008-02-06 23:50 ` [patch 00/73] 2.6.23-stable review Greg KH
2008-02-06 23:50 ` [patch 01/73] SPARC64: Fix sparc64 cpu cross call hangs Greg KH
2008-02-06 23:50 ` Greg KH [this message]
2008-02-06 23:50 ` [patch 03/73] dm crypt: fix write endio Greg KH
2008-02-06 23:50 ` [patch 04/73] dm crypt: use bio_add_page Greg KH
2008-02-06 23:51 ` [patch 05/73] ACPI: video_device_list corruption Greg KH
2008-02-06 23:51 ` [patch 06/73] ACPI: thinkpad-acpi: fix lenovo keymap for brightness Greg KH
2008-02-06 23:51 ` [patch 07/73] SPARC64: Fix memory controller register access when non-SMP Greg KH
2008-02-06 23:51 ` [patch 08/73] SPARC64: Fix two kernel linear mapping setup bugs Greg KH
2008-02-06 23:51 ` [patch 09/73] IPSEC: Fix potential dst leak in xfrm_lookup Greg KH
2008-02-06 23:51 ` [patch 10/73] VLAN: Lost rtnl_unlock() in vlan_ioctl() Greg KH
2008-02-06 23:51 ` [patch 11/73] tty: fix logic change introduced by wait_event_interruptible_timeout() Greg KH
2008-02-06 23:51 ` [patch 12/73] IPV4 raw: Strengthen check on validity of iph->ihl Greg KH
2008-02-06 23:51 ` [patch 13/73] sky2: disable rx checksum on Yukon XL Greg KH
2008-02-06 23:51 ` [patch 14/73] sky2: RX lockup fix Greg KH
2008-02-06 23:51 ` [patch 15/73] POWERPC: Change fallocate to match unistd.h on powerpc Greg KH
2008-02-06 23:51 ` [patch 16/73] X25: Add missing x25_neigh_put Greg KH
2008-02-06 23:51 ` [patch 17/73] NET: mcs7830 passes msecs instead of jiffies to usb_control_msg Greg KH
2008-02-06 23:51 ` [patch 18/73] NET: kaweth was forgotten in msec switchover of usb_start_wait_urb Greg KH
2008-02-06 23:51 ` [patch 19/73] IRDA: irda_create() nuke user triggable printk Greg KH
2008-02-06 23:51 ` [patch 20/73] INET: Fix netdev renaming and inet address labels Greg KH
2008-02-06 23:52 ` [patch 21/73] CONNECTOR: Dont touch queue dev after decrement of ref count Greg KH
2008-02-06 23:52 ` [patch 22/73] ATM: Check IP header validity in mpc_send_packet Greg KH
2008-02-06 23:52 ` [patch 23/73] IPV4 ROUTE: ip_rt_dump() is unecessary slow Greg KH
2008-02-06 23:52 ` [patch 24/73] ATM: delay irq setup until card is configured Greg KH
2008-02-06 23:52 ` [patch 25/73] IPSEC: Avoid undefined shift operation when testing algorithm ID Greg KH
2008-02-06 23:52 ` [patch 26/73] NET: Correct two mistaken skb_reset_mac_header() conversions Greg KH
2008-02-06 23:52 ` [patch 27/73] IPV4: ip_gre: set mac_header correctly in receive path Greg KH
2008-02-06 23:52 ` [patch 28/73] CASSINI: Fix endianness bug Greg KH
2008-02-06 23:52 ` [patch 29/73] CASSINI: Revert dont touch page_count Greg KH
2008-02-06 23:52 ` [patch 30/73] CASSINI: Set skb->truesize properly on receive packets Greg KH
2008-02-06 23:52 ` [patch 31/73] SPARC64: Fix OOPS in dma_sync_*_for_device() Greg KH
2008-02-06 23:52 ` [patch 32/73] SPARC64: Implement pci_resource_to_user() Greg KH
2008-02-06 23:52 ` [patch 33/73] ACPICA: fix acpi-cpufreq boot crash due to _PSD return-by-reference Greg KH
2008-02-06 23:52 ` [patch 34/73] ACPI: Not register gsi for PCI IDE controller in legacy mode Greg KH
2008-02-06 23:52 ` [patch 35/73] ACPICA: fix acpi_serialize hang regression Greg KH
2008-02-06 23:53 ` [patch 36/73] ACPI: apply quirk_ich6_lpc_acpi to more ICH8 and ICH9 Greg KH
2008-02-06 23:53 ` [patch 37/73] PM: ACPI and APM must not be enabled at the same time Greg KH
2008-02-06 23:53 ` [patch 38/73] CRYPTO: padlock: Fix spurious ECB page fault Greg KH
2008-02-06 23:53 ` [patch 39/73] USB: update sierra.c with latest device ids that are in 2.6.24-rc7 Greg KH
2008-02-06 23:53 ` [patch 40/73] clockevents: fix reprogramming decision in oneshot broadcast Greg KH
2008-02-06 23:53 ` [patch 41/73] Freezer: Fix APM emulation breakage Greg KH
2008-02-06 23:53 ` [patch 42/73] vfs: coredumping fix (CVE-2007-6206) Greg KH
2008-02-06 23:53 ` [patch 43/73] quicklists: do not release off node pages early Greg KH
2008-02-06 23:53 ` [patch 44/73] quicklists: Only consider memory that can be used with GFP_KERNEL Greg KH
2008-02-06 23:53 ` [patch 45/73] chelsio: Fix skb->dev setting Greg KH
2008-02-06 23:53 ` [patch 46/73] cxgb: fix T2 GSO Greg KH
2008-02-06 23:53 ` [patch 47/73] cxgb: fix stats Greg KH
2008-02-06 23:53 ` [patch 48/73] Input: implement proper locking in input core Greg KH
2008-02-06 23:53 ` [patch 49/73] Input: evdev - implement proper locking Greg KH
2008-02-06 23:53 ` [patch 50/73] Input: mousedev " Greg KH
2008-02-06 23:53 ` [patch 51/73] Input: joydev " Greg KH
2008-02-06 23:53 ` [patch 52/73] Input: tsdev " Greg KH
2008-02-06 23:53 ` [patch 53/73] Input: fix open count handling in input interfaces Greg KH
2008-02-06 23:53 ` [patch 54/73] CIFS: Respect umask when using POSIX mkdir Greg KH
2008-02-06 23:53 ` [patch 55/73] m68k: Export cachectl.h Greg KH
2008-02-06 23:53 ` [patch 56/73] VM/Security: add security hook to do_brk (CVE-2007-6434) Greg KH
2008-02-06 23:54 ` [patch 57/73] security: protect from stack expantion into low vm addresses Greg KH
2008-02-06 23:54 ` [patch 58/73] md: fix data corruption when a degraded raid5 array is reshaped Greg KH
2008-02-06 23:54 ` [patch 59/73] knfsd: Allow NFSv2/3 WRITE calls to succeed when krb5i etc is used Greg KH
2008-02-06 23:54 ` [patch 60/73] vm audit: add VM_DONTEXPAND to mmap for drivers that need it (CVE-2008-0007) Greg KH
2008-02-06 23:54 ` [patch 61/73] sata_promise: ASIC PRD table bug workaround Greg KH
2008-02-06 23:54 ` [patch 62/73] ia64: Fix unaligned handler for floating point instructions with base update Greg KH
2008-02-06 23:54 ` [patch 63/73] Fix unbalanced helper_lock in kernel/kmod.c Greg KH
2008-02-06 23:54 ` [patch 64/73] spi: omap2_mcspi PIO RX fix Greg KH
2008-02-06 23:54 ` [patch 65/73] libata: port and host should be stopped before hardware resources are released Greg KH
2008-02-06 23:54 ` [patch 66/73] fix oops on rmmod capidrv Greg KH
2008-02-06 23:54 ` [patch 67/73] Netfilter: bridge: fix double POST_ROUTING invocation Greg KH
2008-02-06 23:54 ` [patch 68/73] Netfilter: bridge-netfilter: fix net_device refcnt leaks Greg KH
2008-02-06 23:54 ` [patch 69/73] Fix dirty page accounting leak with ext3 data=journal Greg KH
2008-02-06 23:54 ` [patch 70/73] forcedeth: mac address mcp77/79 Greg KH
2008-02-06 23:54 ` [patch 71/73] atl1: fix frame length bug Greg KH
2008-02-06 23:54 ` [patch 72/73] ACPI: sync blacklist w/ latest Greg KH
2008-02-06 23:54 ` [patch 73/73] PCI: Fix fakephp deadlock Greg KH
2008-02-08 5:31 ` [stable] [patch 00/73] 2.6.23-stable review Greg KH
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=20080206235051.GC13121@suse.de \
--to=gregkh@suse.de \
--cc=agk@redhat.com \
--cc=akpm@linux-foundation.org \
--cc=alan@lxorguk.ukuu.org.uk \
--cc=cavokz@gmail.com \
--cc=cebbert@redhat.com \
--cc=chuckw@quantumlinux.com \
--cc=davej@redhat.com \
--cc=dm-devel@redhat.com \
--cc=j-nomura@ce.jp.nec.com \
--cc=jmforbes@linuxtx.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mkrufky@linuxtv.org \
--cc=rdunlap@xenotime.net \
--cc=reviews@ml.cw.f00f.org \
--cc=stable@kernel.org \
--cc=torvalds@linux-foundation.org \
--cc=tytso@mit.edu \
--cc=zwane@arm.linux.org.uk \
--subject='Re: [patch 02/73] dm: table detect io beyond device' \
/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
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).