[lxc-devel] [RFC PATCH 10/11] loop: Assign devices to current_user_ns()

Seth Forshee seth.forshee at canonical.com
Wed May 14 21:34:58 UTC 2014


loop-control is now global to user namespaces, meaning that any
namespace can use LOOP_CTL_GET_FREE to request a loop device. The
namespace won't necessarily be able to use the device, however.

Update loop to search only for devices matching current_user_ns()
when finding free devices, and to set the device's owning
namespace to current_user_ns() when a new device is added. This
will cause the devices to appear in that namespace's devtmpfs
super block, where it can be used.

This should generally be safe, since only the namespace used to
request the device should see it in devtmpfs, avoiding accidental
use by another namespace. Only a user priveleged enough to mknod
will be able to access the same device, and such access is
unlikely to be accidental.

Signed-off-by: Seth Forshee <seth.forshee at canonical.com>
---
 drivers/block/loop.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/drivers/block/loop.c b/drivers/block/loop.c
index f0e41a372c24..66bd938bcc1c 100644
--- a/drivers/block/loop.c
+++ b/drivers/block/loop.c
@@ -75,6 +75,8 @@
 #include <linux/sysfs.h>
 #include <linux/miscdevice.h>
 #include <linux/falloc.h>
+#include <linux/notifier.h>
+#include <linux/user_namespace.h>
 #include "loop.h"
 
 #include <asm/uaccess.h>
@@ -1674,6 +1676,7 @@ static int loop_add(struct loop_device **l, int i)
 	disk->private_data	= lo;
 	disk->queue		= lo->lo_queue;
 	sprintf(disk->disk_name, "loop%d", i);
+	dev_set_ns(disk_to_dev(disk), current_user_ns());
 	add_disk(disk);
 	*l = lo;
 	return lo->lo_number;
@@ -1690,6 +1693,7 @@ out:
 
 static void loop_remove(struct loop_device *lo)
 {
+	dev_set_ns(disk_to_dev(lo->lo_disk), &init_user_ns);
 	del_gendisk(lo->lo_disk);
 	blk_cleanup_queue(lo->lo_queue);
 	put_disk(lo->lo_disk);
@@ -1701,7 +1705,8 @@ static int find_free_cb(int id, void *ptr, void *data)
 	struct loop_device *lo = ptr;
 	struct loop_device **l = data;
 
-	if (lo->lo_state == Lo_unbound) {
+	if (lo->lo_state == Lo_unbound &&
+	    disk_to_dev(lo->lo_disk)->ns == current_user_ns()) {
 		*l = lo;
 		return 1;
 	}
-- 
1.9.1



More information about the lxc-devel mailing list