From: Greg Kroah-Hartman Date: Tue, 17 Jan 2012 18:33:17 +0000 (-0800) Subject: 3.2-stable patches X-Git-Tag: v3.1.10~2 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=696ac973c5600b9b78346dc97728c229d68ec0e0;p=thirdparty%2Fkernel%2Fstable-queue.git 3.2-stable patches added patches: block-fail-scsi-passthrough-ioctls-on-partition-devices.patch dm-do-not-forward-ioctls-from-logical-volumes-to-the.patch --- diff --git a/queue-3.2/block-fail-scsi-passthrough-ioctls-on-partition-devices.patch b/queue-3.2/block-fail-scsi-passthrough-ioctls-on-partition-devices.patch new file mode 100644 index 00000000000..a5461d4c867 --- /dev/null +++ b/queue-3.2/block-fail-scsi-passthrough-ioctls-on-partition-devices.patch @@ -0,0 +1,156 @@ +From 0bfc96cb77224736dfa35c3c555d37b3646ef35e Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Thu, 12 Jan 2012 16:01:28 +0100 +Subject: block: fail SCSI passthrough ioctls on partition devices + +From: Paolo Bonzini + +commit 0bfc96cb77224736dfa35c3c555d37b3646ef35e upstream. + +Linux allows executing the SG_IO ioctl on a partition or 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 only to part of the disk. + +This patch lets partitions forward a small set of harmless ioctls; +others are logged with printk so that we can see which ioctls are +actually sent. In my tests only CDROM_GET_CAPABILITY actually occurred. +Of course it was being sent to a (partition on a) hard disk, so it would +have failed with ENOTTY and the patch isn't changing anything in +practice. Still, I'm treating it specially to avoid spamming the logs. + +In principle, this restriction should include programs running with +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. However, for +now programs with CAP_SYS_RAWIO will still be allowed to send the +ioctls. Their actions will still be logged. + +This patch does not affect the non-libata IDE driver. That driver +however already tests for bd != bd->bd_contains before issuing some +ioctl; it could be restricted further to forbid these ioctls even for +programs running with CAP_SYS_ADMIN/CAP_SYS_RAWIO. + +Cc: linux-scsi@vger.kernel.org +Cc: Jens Axboe +Cc: James Bottomley +Signed-off-by: Paolo Bonzini +[ Make it also print the command name when warning - Linus ] +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + block/scsi_ioctl.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ + drivers/scsi/sd.c | 11 +++++++++-- + include/linux/blkdev.h | 1 + + 3 files changed, 55 insertions(+), 2 deletions(-) + +--- a/block/scsi_ioctl.c ++++ b/block/scsi_ioctl.c +@@ -24,6 +24,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -690,9 +691,53 @@ int scsi_cmd_ioctl(struct request_queue + } + 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 these is particularly useful on a partition, ++ * but they are 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; ++ case CDROM_GET_CAPABILITY: ++ /* Keep this until we remove the printk below. udev sends it ++ * and we do not want to spam dmesg about it. CD-ROMs do ++ * not have partitions, so we get here only for disks. ++ */ ++ return -ENOIOCTLCMD; ++ default: ++ break; ++ } ++ ++ /* In particular, rule out all resets and host-specific ioctls. */ ++ printk_ratelimited(KERN_WARNING ++ "%s: sending ioctl %x to a partition!\n", current->comm, cmd); ++ ++ return capable(CAP_SYS_RAWIO) ? 0 : -ENOIOCTLCMD; ++} ++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); +--- a/drivers/scsi/sd.c ++++ b/drivers/scsi/sd.c +@@ -1074,6 +1074,10 @@ static int sd_ioctl(struct block_device + SCSI_LOG_IOCTL(1, sd_printk(KERN_INFO, sdkp, "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 +@@ -1266,6 +1270,11 @@ static int sd_compat_ioctl(struct block_ + 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 +@@ -1277,8 +1286,6 @@ static int sd_compat_ioctl(struct block_ + return -ENODEV; + + if (sdev->host->hostt->compat_ioctl) { +- int ret; +- + ret = sdev->host->hostt->compat_ioctl(sdev, cmd, (void __user *)arg); + + return ret; +--- a/include/linux/blkdev.h ++++ b/include/linux/blkdev.h +@@ -675,6 +675,7 @@ extern int blk_insert_cloned_request(str + struct request *rq); + extern void blk_delay_queue(struct request_queue *, unsigned long); + 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, diff --git a/queue-3.2/dm-do-not-forward-ioctls-from-logical-volumes-to-the.patch b/queue-3.2/dm-do-not-forward-ioctls-from-logical-volumes-to-the.patch new file mode 100644 index 00000000000..777586e567d --- /dev/null +++ b/queue-3.2/dm-do-not-forward-ioctls-from-logical-volumes-to-the.patch @@ -0,0 +1,84 @@ +From ec8013beddd717d1740cfefb1a9b900deef85462 Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Thu, 12 Jan 2012 16:01:29 +0100 +Subject: dm: do not forward ioctls from logical volumes to the + underlying device + +From: Paolo Bonzini + +commit ec8013beddd717d1740cfefb1a9b900deef85462 upstream. + +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 +Cc: dm-devel@redhat.com +Signed-off-by: Paolo Bonzini +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/md/dm-flakey.c | 11 ++++++++++- + drivers/md/dm-linear.c | 12 +++++++++++- + drivers/md/dm-mpath.c | 6 ++++++ + 3 files changed, 27 insertions(+), 2 deletions(-) + +--- a/drivers/md/dm-flakey.c ++++ b/drivers/md/dm-flakey.c +@@ -368,8 +368,17 @@ static int flakey_status(struct dm_targe + static int flakey_ioctl(struct dm_target *ti, unsigned int cmd, unsigned long arg) + { + struct flakey_c *fc = ti->private; ++ struct dm_dev *dev = fc->dev; ++ int r = 0; + +- return __blkdev_driver_ioctl(fc->dev->bdev, fc->dev->mode, cmd, arg); ++ /* ++ * Only pass ioctls through if the device sizes match exactly. ++ */ ++ if (fc->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 flakey_merge(struct dm_target *ti, struct bvec_merge_data *bvm, +--- a/drivers/md/dm-linear.c ++++ b/drivers/md/dm-linear.c +@@ -116,7 +116,17 @@ static int linear_ioctl(struct dm_target + 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, +--- a/drivers/md/dm-mpath.c ++++ b/drivers/md/dm-mpath.c +@@ -1520,6 +1520,12 @@ static int multipath_ioctl(struct dm_tar + + spin_unlock_irqrestore(&m->lock, flags); + ++ /* ++ * Only pass ioctls through if the device sizes match exactly. ++ */ ++ if (!r && 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); + } + diff --git a/queue-3.2/series b/queue-3.2/series index 67514967ff0..2c16d0c5483 100644 --- a/queue-3.2/series +++ b/queue-3.2/series @@ -88,3 +88,5 @@ hid-multitouch-add-support-for-3m-32.patch hid-hid-multitouch-add-support-9-new-xiroku-devices.patch fix-cputime-overflow-in-uptime_proc_show.patch block-add-and-use-scsi_blk_cmd_ioctl.patch +block-fail-scsi-passthrough-ioctls-on-partition-devices.patch +dm-do-not-forward-ioctls-from-logical-volumes-to-the.patch