lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:	Wed, 14 May 2014 16:34:56 -0500
From:	Seth Forshee <seth.forshee@...onical.com>
To:	linux-kernel@...r.kernel.org
Cc:	Greg Kroah-Hartman <gregkh@...uxfoundation.org>,
	Jens Axboe <axboe@...nel.dk>, Arnd Bergmann <arnd@...db.de>,
	Eric Biederman <ebiederm@...ssion.com>,
	Serge Hallyn <serge.hallyn@...onical.com>,
	lxc-devel@...ts.linuxcontainers.org,
	Seth Forshee <seth.forshee@...onical.com>
Subject: [RFC PATCH 08/11] block: Allow blkdev ioctls within user namespaces

Many blkdev ioctls require CAP_SYS_ADMIN, preventing them from
being used on block devices owned by unpriveleged user
namespaces. Change this to requiring only CAP_SYS_ADMIN within
the namespace which owns the device. Most devices are owned by
init_user_ns, and in that case this check is equivalent.

Signed-off-by: Seth Forshee <seth.forshee@...onical.com>
---
 block/compat_ioctl.c |  3 ++-
 block/ioctl.c        | 16 ++++++++--------
 2 files changed, 10 insertions(+), 9 deletions(-)

diff --git a/block/compat_ioctl.c b/block/compat_ioctl.c
index fbd5a67cb773..b16745d14ac2 100644
--- a/block/compat_ioctl.c
+++ b/block/compat_ioctl.c
@@ -10,6 +10,7 @@
 #include <linux/syscalls.h>
 #include <linux/types.h>
 #include <linux/uaccess.h>
+#include <linux/user_namespace.h>
 
 static int compat_put_ushort(unsigned long arg, unsigned short val)
 {
@@ -725,7 +726,7 @@ long compat_blkdev_ioctl(struct file *file, unsigned cmd, unsigned long arg)
 					 !blk_queue_nonrot(bdev_get_queue(bdev)));
 	case BLKRASET: /* compatible, but no compat_ptr (!) */
 	case BLKFRASET:
-		if (!capable(CAP_SYS_ADMIN))
+		if (!ns_capable(disk_to_dev(disk)->ns, CAP_SYS_ADMIN))
 			return -EACCES;
 		bdi = blk_get_backing_dev_info(bdev);
 		if (bdi == NULL)
diff --git a/block/ioctl.c b/block/ioctl.c
index 7d5c3b20af45..45bb28d59b56 100644
--- a/block/ioctl.c
+++ b/block/ioctl.c
@@ -7,12 +7,13 @@
 #include <linux/backing-dev.h>
 #include <linux/fs.h>
 #include <linux/blktrace_api.h>
+#include <linux/user_namespace.h>
 #include <asm/uaccess.h>
 
 static int blkpg_ioctl(struct block_device *bdev, struct blkpg_ioctl_arg __user *arg)
 {
 	struct block_device *bdevp;
-	struct gendisk *disk;
+	struct gendisk *disk = bdev->bd_disk;
 	struct hd_struct *part, *lpart;
 	struct blkpg_ioctl_arg a;
 	struct blkpg_partition p;
@@ -20,13 +21,12 @@ static int blkpg_ioctl(struct block_device *bdev, struct blkpg_ioctl_arg __user
 	long long start, length;
 	int partno;
 
-	if (!capable(CAP_SYS_ADMIN))
+	if (!ns_capable(disk_to_dev(disk)->ns, CAP_SYS_ADMIN))
 		return -EACCES;
 	if (copy_from_user(&a, arg, sizeof(struct blkpg_ioctl_arg)))
 		return -EFAULT;
 	if (copy_from_user(&p, a.data, sizeof(struct blkpg_partition)))
 		return -EFAULT;
-	disk = bdev->bd_disk;
 	if (bdev != bdev->bd_contains)
 		return -EINVAL;
 	partno = p.pno;
@@ -157,7 +157,7 @@ static int blkdev_reread_part(struct block_device *bdev)
 
 	if (!disk_part_scan_enabled(disk) || bdev != bdev->bd_contains)
 		return -EINVAL;
-	if (!capable(CAP_SYS_ADMIN))
+	if (!ns_capable(disk_to_dev(disk)->ns, CAP_SYS_ADMIN))
 		return -EACCES;
 	if (!mutex_trylock(&bdev->bd_mutex))
 		return -EBUSY;
@@ -281,7 +281,7 @@ int blkdev_ioctl(struct block_device *bdev, fmode_t mode, unsigned cmd,
 
 	switch(cmd) {
 	case BLKFLSBUF:
-		if (!capable(CAP_SYS_ADMIN))
+		if (!ns_capable(disk_to_dev(disk)->ns, CAP_SYS_ADMIN))
 			return -EACCES;
 
 		ret = __blkdev_driver_ioctl(bdev, mode, cmd, arg);
@@ -296,7 +296,7 @@ int blkdev_ioctl(struct block_device *bdev, fmode_t mode, unsigned cmd,
 		ret = __blkdev_driver_ioctl(bdev, mode, cmd, arg);
 		if (!is_unrecognized_ioctl(ret))
 			return ret;
-		if (!capable(CAP_SYS_ADMIN))
+		if (!ns_capable(disk_to_dev(disk)->ns, CAP_SYS_ADMIN))
 			return -EACCES;
 		if (get_user(n, (int __user *)(arg)))
 			return -EFAULT;
@@ -380,7 +380,7 @@ int blkdev_ioctl(struct block_device *bdev, fmode_t mode, unsigned cmd,
 		return put_ushort(arg, !blk_queue_nonrot(bdev_get_queue(bdev)));
 	case BLKRASET:
 	case BLKFRASET:
-		if(!capable(CAP_SYS_ADMIN))
+		if(!ns_capable(disk_to_dev(disk)->ns, CAP_SYS_ADMIN))
 			return -EACCES;
 		bdi = blk_get_backing_dev_info(bdev);
 		if (bdi == NULL)
@@ -389,7 +389,7 @@ int blkdev_ioctl(struct block_device *bdev, fmode_t mode, unsigned cmd,
 		return 0;
 	case BLKBSZSET:
 		/* set the logical block size */
-		if (!capable(CAP_SYS_ADMIN))
+		if (!ns_capable(disk_to_dev(disk)->ns, CAP_SYS_ADMIN))
 			return -EACCES;
 		if (!arg)
 			return -EINVAL;
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists