[kernel] r18462 - in dists/squeeze-security/linux-2.6/debian: . patches/bugfix/all patches/series
Dann Frazier
dannf at alioth.debian.org
Sun Jan 8 10:33:52 UTC 2012
Author: dannf
Date: Sun Jan 8 10:33:51 2012
New Revision: 18462
Log:
Restrict ioctl forwarding on partitions and logical volumes (CVE-2011-4127)
Added:
dists/squeeze-security/linux-2.6/debian/patches/bugfix/all/add-scsi_cmd_blk_ioctl-wrapper.patch
dists/squeeze-security/linux-2.6/debian/patches/bugfix/all/limit-ioctls-forwarded-to-non-scsi-devices.patch
dists/squeeze-security/linux-2.6/debian/patches/bugfix/all/treat-lvs-on-one-pv-like-a-partition.patch
dists/squeeze-security/linux-2.6/debian/patches/series/35squeeze3
Modified:
dists/squeeze-security/linux-2.6/debian/changelog
Modified: dists/squeeze-security/linux-2.6/debian/changelog
==============================================================================
--- dists/squeeze-security/linux-2.6/debian/changelog Sun Jan 8 03:28:07 2012 (r18461)
+++ dists/squeeze-security/linux-2.6/debian/changelog Sun Jan 8 10:33:51 2012 (r18462)
@@ -1,3 +1,9 @@
+linux-2.6 (2.6.32-35squeeze3) UNRELEASED; urgency=low
+
+ * Restrict ioctl forwarding on partitions and logical volumes (CVE-2011-4127)
+
+ -- dann frazier <dannf at debian.org> Fri, 06 Jan 2012 18:46:21 -0700
+
linux-2.6 (2.6.32-35squeeze2) stable-security; urgency=high
* Fix regression in /proc/<pid>/maps fixes for CVE-2011-1020
Added: dists/squeeze-security/linux-2.6/debian/patches/bugfix/all/add-scsi_cmd_blk_ioctl-wrapper.patch
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ dists/squeeze-security/linux-2.6/debian/patches/bugfix/all/add-scsi_cmd_blk_ioctl-wrapper.patch Sun Jan 8 10:33:51 2012 (r18462)
@@ -0,0 +1,157 @@
+From 3831a172b179a5b74142aca314fe84b79e115410 Mon Sep 17 00:00:00 2001
+From: dann frazier <dannf at debian.org>
+Date: Fri, 6 Jan 2012 14:30:17 -0700
+Subject: [PATCH 1/3] Introduce a wrapper around scsi_cmd_ioctl that takes a
+ block device. The function will then be enhanced to
+ detect partition block devices and, in that case,
+ subject the ioctls to whitelisting.
+
+Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
+[dannf: backported to Debian's 2.6.32]
+---
+ block/scsi_ioctl.c | 7 +++++++
+ drivers/block/cciss.c | 6 +++---
+ drivers/block/ub.c | 14 +-------------
+ drivers/block/virtio_blk.c | 4 ++--
+ drivers/cdrom/cdrom.c | 3 +--
+ drivers/scsi/sd.c | 2 +-
+ include/linux/blkdev.h | 2 ++
+ 7 files changed, 17 insertions(+), 21 deletions(-)
+
+diff --git a/block/scsi_ioctl.c b/block/scsi_ioctl.c
+index 1d5a780..114ee29 100644
+--- a/block/scsi_ioctl.c
++++ b/block/scsi_ioctl.c
+@@ -689,6 +689,13 @@ int scsi_cmd_ioctl(struct request_queue *q, struct gendisk *bd_disk, fmode_t mod
+ }
+ EXPORT_SYMBOL(scsi_cmd_ioctl);
+
++int scsi_cmd_blk_ioctl(struct block_device *bd, fmode_t mode,
++ unsigned int cmd, void __user *arg)
++{
++ return scsi_cmd_ioctl(bd->bd_disk->queue, bd->bd_disk, mode, cmd, arg);
++}
++EXPORT_SYMBOL(scsi_cmd_blk_ioctl);
++
+ int __init blk_scsi_ioctl_init(void)
+ {
+ blk_set_cmd_filter_defaults(&blk_default_cmd_filter);
+diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c
+index ca9c548..68b90d9 100644
+--- a/drivers/block/cciss.c
++++ b/drivers/block/cciss.c
+@@ -1583,7 +1583,7 @@ static int cciss_ioctl(struct block_device *bdev, fmode_t mode,
+ return status;
+ }
+
+- /* scsi_cmd_ioctl handles these, below, though some are not */
++ /* scsi_cmd_blk_ioctl handles these, below, though some are not */
+ /* very meaningful for cciss. SG_IO is the main one people want. */
+
+ case SG_GET_VERSION_NUM:
+@@ -1594,9 +1594,9 @@ static int cciss_ioctl(struct block_device *bdev, fmode_t mode,
+ case SG_EMULATED_HOST:
+ case SG_IO:
+ case SCSI_IOCTL_SEND_COMMAND:
+- return scsi_cmd_ioctl(disk->queue, disk, mode, cmd, argp);
++ return scsi_cmd_blk_ioctl(bdev, mode, cmd, argp);
+
+- /* scsi_cmd_ioctl would normally handle these, below, but */
++ /* scsi_cmd_blk_ioctl would normally handle these, below, but */
+ /* they aren't a good fit for cciss, as CD-ROMs are */
+ /* not supported, and we don't have any bus/target/lun */
+ /* which we present to the kernel. */
+diff --git a/drivers/block/ub.c b/drivers/block/ub.c
+index c739b20..5e0ac9a 100644
+--- a/drivers/block/ub.c
++++ b/drivers/block/ub.c
+@@ -1721,18 +1721,6 @@ static int ub_bd_release(struct gendisk *disk, fmode_t mode)
+ }
+
+ /*
+- * The ioctl interface.
+- */
+-static int ub_bd_ioctl(struct block_device *bdev, fmode_t mode,
+- unsigned int cmd, unsigned long arg)
+-{
+- struct gendisk *disk = bdev->bd_disk;
+- void __user *usermem = (void __user *) arg;
+-
+- return scsi_cmd_ioctl(disk->queue, disk, mode, cmd, usermem);
+-}
+-
+-/*
+ * This is called by check_disk_change if we reported a media change.
+ * The main onjective here is to discover the features of the media such as
+ * the capacity, read-only status, etc. USB storage generally does not
+@@ -1793,7 +1781,7 @@ static const struct block_device_operations ub_bd_fops = {
+ .owner = THIS_MODULE,
+ .open = ub_bd_open,
+ .release = ub_bd_release,
+- .locked_ioctl = ub_bd_ioctl,
++ .locked_ioctl = scsi_cmd_blk_ioctl,
+ .media_changed = ub_bd_media_changed,
+ .revalidate_disk = ub_bd_revalidate,
+ };
+diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c
+index 51042f0..44d019b 100644
+--- a/drivers/block/virtio_blk.c
++++ b/drivers/block/virtio_blk.c
+@@ -200,8 +200,8 @@ static int virtblk_ioctl(struct block_device *bdev, fmode_t mode,
+ if (!virtio_has_feature(vblk->vdev, VIRTIO_BLK_F_SCSI))
+ return -ENOTTY;
+
+- return scsi_cmd_ioctl(disk->queue, disk, mode, cmd,
+- (void __user *)data);
++ return scsi_cmd_blk_ioctl(bdev, mode, cmd,
++ (void __user *)data);
+ }
+
+ /* We provide getgeo only to please some old bootloader/partitioning tools */
+diff --git a/drivers/cdrom/cdrom.c b/drivers/cdrom/cdrom.c
+index 614da5b..59cccc9 100644
+--- a/drivers/cdrom/cdrom.c
++++ b/drivers/cdrom/cdrom.c
+@@ -2684,12 +2684,11 @@ int cdrom_ioctl(struct cdrom_device_info *cdi, struct block_device *bdev,
+ {
+ void __user *argp = (void __user *)arg;
+ int ret;
+- struct gendisk *disk = bdev->bd_disk;
+
+ /*
+ * Try the generic SCSI command ioctl's first.
+ */
+- ret = scsi_cmd_ioctl(disk->queue, disk, mode, cmd, argp);
++ ret = scsi_cmd_blk_ioctl(bdev, mode, cmd, argp);
+ if (ret != -ENOTTY)
+ return ret;
+
+diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
+index 160b47e..a5f3728 100644
+--- a/drivers/scsi/sd.c
++++ b/drivers/scsi/sd.c
+@@ -840,7 +840,7 @@ static int sd_ioctl(struct block_device *bdev, fmode_t mode,
+ case SCSI_IOCTL_GET_BUS_NUMBER:
+ return scsi_ioctl(sdp, cmd, p);
+ default:
+- error = scsi_cmd_ioctl(disk->queue, disk, mode, cmd, p);
++ error = scsi_cmd_blk_ioctl(bdev, mode, cmd, p);
+ if (error != -ENOTTY)
+ return error;
+ }
+diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
+index 57da328..025b78b 100644
+--- a/include/linux/blkdev.h
++++ b/include/linux/blkdev.h
+@@ -779,6 +779,8 @@ extern void blk_plug_device(struct request_queue *);
+ extern void blk_plug_device_unlocked(struct request_queue *);
+ extern int blk_remove_plug(struct request_queue *);
+ extern void blk_recount_segments(struct request_queue *, struct bio *);
++extern int scsi_cmd_blk_ioctl(struct block_device *, fmode_t,
++ unsigned int, void __user *);
+ extern int scsi_cmd_ioctl(struct request_queue *, struct gendisk *, fmode_t,
+ unsigned int, void __user *);
+ extern int sg_scsi_ioctl(struct request_queue *, struct gendisk *, fmode_t,
+--
+1.7.8.2
+
Added: dists/squeeze-security/linux-2.6/debian/patches/bugfix/all/limit-ioctls-forwarded-to-non-scsi-devices.patch
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ dists/squeeze-security/linux-2.6/debian/patches/bugfix/all/limit-ioctls-forwarded-to-non-scsi-devices.patch Sun Jan 8 10:33:51 2012 (r18462)
@@ -0,0 +1,140 @@
+From 264713ad6e27fcd33eb2095a98ffa6d34ce2ea4b Mon Sep 17 00:00:00 2001
+From: dann frazier <dannf at debian.org>
+Date: Fri, 6 Jan 2012 14:31:06 -0700
+Subject: [PATCH 2/3] Linux allows executing the SG_IO ioctl on a partition or
+ even on an LVM volume, and will pass the command to the
+ underlying block device. This is well-known, but it is
+ also a large security problem when (via Unix
+ permissions, ACLs, SELinux or a combination thereof) a
+ program or user needs to be granted access to a
+ particular partition or logical volume but not to the
+ full device.
+
+This patch limits the ioctls that are forwarded to non-SCSI devices to
+a few ones that are harmless. This restriction includes programs
+running with the CAP_SYS_RAWIO. If for example I let a program access
+/dev/sda2 and /dev/sdb, it still should not be able to read/write outside
+the boundaries of /dev/sda2 independent of the capabilities.
+
+This patch does not affect the non-libata IDE driver. That driver however
+alreadys test for bd != bd->bd_contains before issuing some ioctl; so,
+programs that do not require CAP_SYS_RAWIO are safe. A workaround is
+just to use libata.
+
+Encryption on the host is a mitigating factor, but it does not provide
+a full solution. In particular it doesn't protect against DoS (write
+random data), replay attacks (reinstate old ciphertext sectors), or
+writes to unencrypted areas including the MBR, the partition table, or
+/boot.
+
+Thanks to Daniel Berrange, Milan Broz, Mike Christie, Alasdair Kergon,
+Petr Matousek, Jeff Moyer, Mike Snitzer and others for help discussing
+this issue.
+
+Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
+[dannf: backported to Debian's 2.6.32]
+---
+ block/scsi_ioctl.c | 34 ++++++++++++++++++++++++++++++++++
+ drivers/scsi/sd.c | 11 +++++++++--
+ include/linux/blkdev.h | 1 +
+ 3 files changed, 44 insertions(+), 2 deletions(-)
+
+diff --git a/block/scsi_ioctl.c b/block/scsi_ioctl.c
+index 114ee29..5cd4e02 100644
+--- a/block/scsi_ioctl.c
++++ b/block/scsi_ioctl.c
+@@ -689,9 +689,43 @@ int scsi_cmd_ioctl(struct request_queue *q, struct gendisk *bd_disk, fmode_t mod
+ }
+ EXPORT_SYMBOL(scsi_cmd_ioctl);
+
++int scsi_verify_blk_ioctl(struct block_device *bd, unsigned int cmd)
++{
++ if (bd && bd == bd->bd_contains)
++ return 0;
++
++ /* Actually none of this is particularly useful on a partition
++ * device, but let's play it safe.
++ */
++ switch (cmd) {
++ case SCSI_IOCTL_GET_IDLUN:
++ case SCSI_IOCTL_GET_BUS_NUMBER:
++ case SCSI_IOCTL_GET_PCI:
++ case SCSI_IOCTL_PROBE_HOST:
++ case SG_GET_VERSION_NUM:
++ case SG_SET_TIMEOUT:
++ case SG_GET_TIMEOUT:
++ case SG_GET_RESERVED_SIZE:
++ case SG_SET_RESERVED_SIZE:
++ case SG_EMULATED_HOST:
++ return 0;
++ default:
++ break;
++ }
++ /* In particular, rule out all resets and host-specific ioctls. */
++ return -ENOTTY;
++}
++EXPORT_SYMBOL(scsi_verify_blk_ioctl);
++
+ int scsi_cmd_blk_ioctl(struct block_device *bd, fmode_t mode,
+ unsigned int cmd, void __user *arg)
+ {
++ int ret;
++
++ ret = scsi_verify_blk_ioctl(bd, cmd);
++ if (ret < 0)
++ return ret;
++
+ return scsi_cmd_ioctl(bd->bd_disk->queue, bd->bd_disk, mode, cmd, arg);
+ }
+ EXPORT_SYMBOL(scsi_cmd_blk_ioctl);
+diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
+index a5f3728..4219572 100644
+--- a/drivers/scsi/sd.c
++++ b/drivers/scsi/sd.c
+@@ -819,6 +819,10 @@ static int sd_ioctl(struct block_device *bdev, fmode_t mode,
+ SCSI_LOG_IOCTL(1, printk("sd_ioctl: disk=%s, cmd=0x%x\n",
+ disk->disk_name, cmd));
+
++ error = scsi_verify_blk_ioctl(bdev, cmd);
++ if (error < 0)
++ return error;
++
+ /*
+ * If we are in the middle of error recovery, don't let anyone
+ * else try and use this device. Also, if error recovery fails, it
+@@ -998,6 +1002,11 @@ static int sd_compat_ioctl(struct block_device *bdev, fmode_t mode,
+ unsigned int cmd, unsigned long arg)
+ {
+ struct scsi_device *sdev = scsi_disk(bdev->bd_disk)->device;
++ int ret;
++
++ ret = scsi_verify_blk_ioctl(bdev, cmd);
++ if (ret < 0)
++ return ret;
+
+ /*
+ * If we are in the middle of error recovery, don't let anyone
+@@ -1009,8 +1018,6 @@ static int sd_compat_ioctl(struct block_device *bdev, fmode_t mode,
+ return -ENODEV;
+
+ if (sdev->host->hostt->compat_ioctl) {
+- int ret;
+-
+ ret = sdev->host->hostt->compat_ioctl(sdev, cmd, (void __user *)arg);
+
+ return ret;
+diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
+index 025b78b..09beade 100644
+--- a/include/linux/blkdev.h
++++ b/include/linux/blkdev.h
+@@ -779,6 +779,7 @@ extern void blk_plug_device(struct request_queue *);
+ extern void blk_plug_device_unlocked(struct request_queue *);
+ extern int blk_remove_plug(struct request_queue *);
+ extern void blk_recount_segments(struct request_queue *, struct bio *);
++extern int scsi_verify_blk_ioctl(struct block_device *, unsigned int);
+ extern int scsi_cmd_blk_ioctl(struct block_device *, fmode_t,
+ unsigned int, void __user *);
+ extern int scsi_cmd_ioctl(struct request_queue *, struct gendisk *, fmode_t,
+--
+1.7.8.2
+
Added: dists/squeeze-security/linux-2.6/debian/patches/bugfix/all/treat-lvs-on-one-pv-like-a-partition.patch
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ dists/squeeze-security/linux-2.6/debian/patches/bugfix/all/treat-lvs-on-one-pv-like-a-partition.patch Sun Jan 8 10:33:51 2012 (r18462)
@@ -0,0 +1,61 @@
+From d4a97721ab45133e6e0d058fb711e0b55fe2e0db Mon Sep 17 00:00:00 2001
+From: dann frazier <dannf at debian.org>
+Date: Fri, 6 Jan 2012 14:35:32 -0700
+Subject: [PATCH 3/3] A logical volume can map to just part of underlying
+ physical volume. In this case, it must be treated like
+ a partition.
+
+Based on a patch from Alasdair G Kergon.
+
+Cc: Alasdair G Kergon <agk at redhat.com>
+Cc: Mike Snitzer <msnitzer at redhat.com>
+Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
+[dannf: backported to Debian's 2.6.32]
+---
+ drivers/md/dm-linear.c | 12 +++++++++++-
+ drivers/md/dm-mpath.c | 6 ++++++
+ 2 files changed, 17 insertions(+), 1 deletions(-)
+
+diff --git a/drivers/md/dm-linear.c b/drivers/md/dm-linear.c
+index 82f7d6e..7ab302d 100644
+--- a/drivers/md/dm-linear.c
++++ b/drivers/md/dm-linear.c
+@@ -116,7 +116,17 @@ static int linear_ioctl(struct dm_target *ti, unsigned int cmd,
+ unsigned long arg)
+ {
+ struct linear_c *lc = (struct linear_c *) ti->private;
+- return __blkdev_driver_ioctl(lc->dev->bdev, lc->dev->mode, cmd, arg);
++ struct dm_dev *dev = lc->dev;
++ int r = 0;
++
++ /*
++ * Only pass ioctls through if the device sizes match exactly.
++ */
++ if (lc->start ||
++ ti->len != i_size_read(dev->bdev->bd_inode) >> SECTOR_SHIFT)
++ r = scsi_verify_blk_ioctl(NULL, cmd);
++
++ return r ? : __blkdev_driver_ioctl(dev->bdev, dev->mode, cmd, arg);
+ }
+
+ static int linear_merge(struct dm_target *ti, struct bvec_merge_data *bvm,
+diff --git a/drivers/md/dm-mpath.c b/drivers/md/dm-mpath.c
+index fcf717c..60d1f93 100644
+--- a/drivers/md/dm-mpath.c
++++ b/drivers/md/dm-mpath.c
+@@ -1459,6 +1459,12 @@ static int multipath_ioctl(struct dm_target *ti, unsigned int cmd,
+
+ spin_unlock_irqrestore(&m->lock, flags);
+
++ /*
++ * Only pass ioctls through if the device sizes match exactly.
++ */
++ if (r == 0 && ti->len != i_size_read(bdev->bd_inode) >> SECTOR_SHIFT)
++ r = scsi_verify_blk_ioctl(NULL, cmd);
++
+ return r ? : __blkdev_driver_ioctl(bdev, mode, cmd, arg);
+ }
+
+--
+1.7.8.2
+
Added: dists/squeeze-security/linux-2.6/debian/patches/series/35squeeze3
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ dists/squeeze-security/linux-2.6/debian/patches/series/35squeeze3 Sun Jan 8 10:33:51 2012 (r18462)
@@ -0,0 +1,3 @@
++ bugfix/all/add-scsi_cmd_blk_ioctl-wrapper.patch
++ bugfix/all/limit-ioctls-forwarded-to-non-scsi-devices.patch
++ bugfix/all/treat-lvs-on-one-pv-like-a-partition.patch
More information about the Kernel-svn-changes
mailing list