stable.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Greg KH <gregkh@linuxfoundation.org>
To: linux-kernel@vger.kernel.org, stable@vger.kernel.org
Cc: torvalds@linux-foundation.org, akpm@linux-foundation.org,
	alan@lxorguk.ukuu.org.uk, Huajun Li <huajun.li.lee@gmail.com>,
	Junichi Nomura <j-nomura@ce.jp.nec.com>,
	Tejun Heo <tj@kernel.org>, Jens Axboe <axboe@kernel.dk>
Subject: [ 29/38] block: Fix NULL pointer dereference in sd_revalidate_disk
Date: Fri, 16 Mar 2012 16:35:16 -0700	[thread overview]
Message-ID: <20120316233449.847487179@linuxfoundation.org> (raw)
In-Reply-To: <20120316233422.GA5461@kroah.com>

3.0-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Jun'ichi Nomura <j-nomura@ce.jp.nec.com>

commit fe316bf2d5847bc5dd975668671a7b1067603bc7 upstream.

Since 2.6.39 (1196f8b), when a driver returns -ENOMEDIUM for open(),
__blkdev_get() calls rescan_partitions() to remove
in-kernel partition structures and raise KOBJ_CHANGE uevent.

However it ends up calling driver's revalidate_disk without open
and could cause oops.

In the case of SCSI:

  process A                  process B
  ----------------------------------------------
  sys_open
    __blkdev_get
      sd_open
        returns -ENOMEDIUM
                             scsi_remove_device
                               <scsi_device torn down>
      rescan_partitions
        sd_revalidate_disk
          <oops>
Oopses are reported here:
http://marc.info/?l=linux-scsi&m=132388619710052

This patch separates the partition invalidation from rescan_partitions()
and use it for -ENOMEDIUM case.

Reported-by: Huajun Li <huajun.li.lee@gmail.com>
Signed-off-by: Jun'ichi Nomura <j-nomura@ce.jp.nec.com>
Acked-by: Tejun Heo <tj@kernel.org>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

---
 fs/block_dev.c        |   16 ++++++++++++----
 fs/partitions/check.c |   48 ++++++++++++++++++++++++++++++++++++++++--------
 include/linux/genhd.h |    1 +
 3 files changed, 53 insertions(+), 12 deletions(-)

--- a/fs/block_dev.c
+++ b/fs/block_dev.c
@@ -1149,8 +1149,12 @@ static int __blkdev_get(struct block_dev
 			 * The latter is necessary to prevent ghost
 			 * partitions on a removed medium.
 			 */
-			if (bdev->bd_invalidated && (!ret || ret == -ENOMEDIUM))
-				rescan_partitions(disk, bdev);
+			if (bdev->bd_invalidated) {
+				if (!ret)
+					rescan_partitions(disk, bdev);
+				else if (ret == -ENOMEDIUM)
+					invalidate_partitions(disk, bdev);
+			}
 			if (ret)
 				goto out_clear;
 		} else {
@@ -1180,8 +1184,12 @@ static int __blkdev_get(struct block_dev
 			if (bdev->bd_disk->fops->open)
 				ret = bdev->bd_disk->fops->open(bdev, mode);
 			/* the same as first opener case, read comment there */
-			if (bdev->bd_invalidated && (!ret || ret == -ENOMEDIUM))
-				rescan_partitions(bdev->bd_disk, bdev);
+			if (bdev->bd_invalidated) {
+				if (!ret)
+					rescan_partitions(bdev->bd_disk, bdev);
+				else if (ret == -ENOMEDIUM)
+					invalidate_partitions(bdev->bd_disk, bdev);
+			}
 			if (ret)
 				goto out_unlock_bdev;
 		}
--- a/fs/partitions/check.c
+++ b/fs/partitions/check.c
@@ -539,17 +539,11 @@ static bool disk_unlock_native_capacity(
 	}
 }
 
-int rescan_partitions(struct gendisk *disk, struct block_device *bdev)
+static int drop_partitions(struct gendisk *disk, struct block_device *bdev)
 {
-	struct parsed_partitions *state = NULL;
 	struct disk_part_iter piter;
 	struct hd_struct *part;
-	int p, highest, res;
-rescan:
-	if (state && !IS_ERR(state)) {
-		kfree(state);
-		state = NULL;
-	}
+	int res;
 
 	if (bdev->bd_part_count)
 		return -EBUSY;
@@ -562,6 +556,24 @@ rescan:
 		delete_partition(disk, part->partno);
 	disk_part_iter_exit(&piter);
 
+	return 0;
+}
+
+int rescan_partitions(struct gendisk *disk, struct block_device *bdev)
+{
+	struct parsed_partitions *state = NULL;
+	struct hd_struct *part;
+	int p, highest, res;
+rescan:
+	if (state && !IS_ERR(state)) {
+		kfree(state);
+		state = NULL;
+	}
+
+	res = drop_partitions(disk, bdev);
+	if (res)
+		return res;
+
 	if (disk->fops->revalidate_disk)
 		disk->fops->revalidate_disk(disk);
 	check_disk_size_change(disk, bdev);
@@ -665,6 +677,26 @@ rescan:
 	return 0;
 }
 
+int invalidate_partitions(struct gendisk *disk, struct block_device *bdev)
+{
+	int res;
+
+	if (!bdev->bd_invalidated)
+		return 0;
+
+	res = drop_partitions(disk, bdev);
+	if (res)
+		return res;
+
+	set_capacity(disk, 0);
+	check_disk_size_change(disk, bdev);
+	bdev->bd_invalidated = 0;
+	/* tell userspace that the media / partition table may have changed */
+	kobject_uevent(&disk_to_dev(disk)->kobj, KOBJ_CHANGE);
+
+	return 0;
+}
+
 unsigned char *read_dev_sector(struct block_device *bdev, sector_t n, Sector *p)
 {
 	struct address_space *mapping = bdev->bd_inode->i_mapping;
--- a/include/linux/genhd.h
+++ b/include/linux/genhd.h
@@ -594,6 +594,7 @@ extern char *disk_name (struct gendisk *
 
 extern int disk_expand_part_tbl(struct gendisk *disk, int target);
 extern int rescan_partitions(struct gendisk *disk, struct block_device *bdev);
+extern int invalidate_partitions(struct gendisk *disk, struct block_device *bdev);
 extern struct hd_struct * __must_check add_partition(struct gendisk *disk,
 						     int partno, sector_t start,
 						     sector_t len, int flags,



  parent reply	other threads:[~2012-03-16 23:35 UTC|newest]

Thread overview: 44+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-03-16 23:34 [ 00/38] 3.0.25-stable review Greg KH
2012-03-16 23:34 ` [ 01/38] ASoC: neo1973: fix neo1973 wm8753 initialization Greg KH
2012-03-16 23:34 ` [ 02/38] aio: fix io_setup/io_destroy race Greg KH
2012-03-16 23:34 ` [ 03/38] aio: fix the "too late munmap()" race Greg KH
2012-03-16 23:34 ` [ 04/38] x86: Derandom delay_tsc for 64 bit Greg KH
2012-03-16 23:34 ` [ 05/38] PCI: ignore pre-1.1 ASPM quirking when ASPM is disabled Greg KH
2012-03-19 10:20   ` Jiri Slaby
2012-03-19 15:46     ` Greg KH
2012-03-19 15:53       ` Matthew Garrett
2012-03-19 16:04       ` Jonathan Nieder
2012-03-19 16:25         ` Greg KH
2012-03-19 16:33           ` Jonathan Nieder
2012-03-16 23:34 ` [ 06/38] firewire: cdev: fix 32 bit userland on 64 bit kernel compat corner cases Greg KH
2012-03-16 23:34 ` [ 07/38] firewire: core: handle ack_busy when fetching the Config ROM Greg KH
2012-03-16 23:34 ` [ 08/38] PM / Driver core: leave runtime PM enabled during system shutdown Greg KH
2012-03-16 23:34 ` [ 09/38] rt2x00: fix random stalls Greg KH
2012-03-16 23:34 ` [ 10/38] vfs: fix return value from do_last() Greg KH
2012-03-16 23:34 ` [ 11/38] vfs: fix double put after complete_walk() Greg KH
2012-03-16 23:34 ` [ 12/38] acer-wmi: support Lenovo ideapad S205 wifi switch Greg KH
2012-03-16 23:35 ` [ 13/38] acer-wmi: Add wireless quirk for Lenovo 3000 N200 Greg KH
2012-03-16 23:35 ` [ 14/38] acer-wmi: check wireless capability flag before register rfkill Greg KH
2012-03-16 23:35 ` [ 15/38] acer-wmi: No wifi rfkill on Lenovo machines Greg KH
2012-03-16 23:35 ` [ 16/38] neighbour: Fixed race condition at tbl->nht Greg KH
2012-03-16 23:35 ` [ 17/38] ipsec: be careful of non existing mac headers Greg KH
2012-03-16 23:35 ` [ 18/38] ppp: fix ppp_mp_reconstruct bad seq errors Greg KH
2012-03-16 23:35 ` [ 19/38] tcp: fix false reordering signal in tcp_shifted_skb Greg KH
2012-03-16 23:35 ` [ 20/38] vmxnet3: Fix transport header size Greg KH
2012-03-16 23:35 ` [ 21/38] tcp: dont fragment SACKed skbs in tcp_mark_head_lost() Greg KH
2012-03-16 23:35 ` [ 22/38] bridge: check return value of ipv6_dev_get_saddr() Greg KH
2012-03-16 23:35 ` [ 23/38] tcp: fix tcp_shift_skb_data() to not shift SACKed data below snd_una Greg KH
2012-03-16 23:35 ` [ 24/38] IPv6: Fix not join all-router mcast group when forwarding set Greg KH
2012-03-16 23:35 ` [ 25/38] atl1c: dont use highprio tx queue Greg KH
2012-03-16 23:35 ` [ 26/38] usb: asix: Patch for Sitecom LN-031 Greg KH
2012-03-16 23:35 ` [ 28/38] regulator: Fix setting selector in tps6524x set_voltage function Greg KH
2012-03-16 23:35 ` Greg KH [this message]
2012-03-16 23:35 ` [ 30/38] block, sx8: fix pointer math issue getting fw version Greg KH
2012-03-16 23:35 ` [ 31/38] block: fix __blkdev_get and add_disk race condition Greg KH
2012-03-16 23:35 ` [ 32/38] Block: use a freezable workqueue for disk-event polling Greg KH
2012-03-16 23:35 ` [ 33/38] sfc: Fix assignment of ip_summed for pre-allocated skbs Greg KH
2012-03-16 23:35 ` [ 34/38] sparc32: Add -Av8 to assembler command line Greg KH
2012-03-16 23:35 ` [ 35/38] compat: Re-add missing asm/compat.h include to fix compile breakage on s390 Greg KH
2012-03-16 23:35 ` [ 36/38] hwmon: (w83627ehf) Fix writing into fan_stop_time for NCT6775F/NCT6776F Greg KH
2012-03-16 23:35 ` [ 37/38] hwmon: (w83627ehf) Fix memory leak in probe function Greg KH
2012-03-16 23:35 ` [ 38/38] i2c-algo-bit: Fix spurious SCL timeouts under heavy load 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=20120316233449.847487179@linuxfoundation.org \
    --to=gregkh@linuxfoundation.org \
    --cc=akpm@linux-foundation.org \
    --cc=alan@lxorguk.ukuu.org.uk \
    --cc=axboe@kernel.dk \
    --cc=huajun.li.lee@gmail.com \
    --cc=j-nomura@ce.jp.nec.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=stable@vger.kernel.org \
    --cc=tj@kernel.org \
    --cc=torvalds@linux-foundation.org \
    /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).