diff options
| author | Hannes Reinecke <hare@suse.de> | 2021-06-10 09:12:44 +0200 |
|---|---|---|
| committer | Hannes Reinecke <hare@suse.de> | 2021-06-10 09:12:44 +0200 |
| commit | eddd528a51cc0838c23fd1436b6d880ccc66ac45 (patch) | |
| tree | c608d9fc964aca545c5bfa0107ddaf3437ddf67c | |
| parent | 147e14e30cde27157d6794c149aa0eb10f578ff1 (diff) | |
| download | scsi-devel-eddd528a51cc0838c23fd1436b6d880ccc66ac45.tar.gz | |
block: user namespace support
Add initial support for user namespace tagging of struct gendisk.
Signed-off-by: Hannes Reinecke <hare@suse.de>
| -rw-r--r-- | block/Kconfig | 7 | ||||
| -rw-r--r-- | block/genhd.c | 85 | ||||
| -rw-r--r-- | include/linux/genhd.h | 3 |
3 files changed, 95 insertions, 0 deletions
diff --git a/block/Kconfig b/block/Kconfig index a2297edfdde88..984cdd91e8c08 100644 --- a/block/Kconfig +++ b/block/Kconfig @@ -114,6 +114,13 @@ config BLK_DEV_THROTTLING_LOW Note, this is an experimental interface and could be changed someday. +config BLK_DEV_USER_NS + bool "Block user namespace support (EXPERIMENTAL)" + help + Make block devices namespace-aware. + + This is an experimental feature; functionality may be limited. + config BLK_CMDLINE_PARSER bool "Block device command line partition parser" help diff --git a/block/genhd.c b/block/genhd.c index 9f8cb7beaad11..6c8f09532113d 100644 --- a/block/genhd.c +++ b/block/genhd.c @@ -864,11 +864,87 @@ static const struct seq_operations partitions_op = { }; #endif +#ifdef CONFIG_BLK_USER_NS +static void *user_grab_current_ns(void) +{ + struct user_namespace *ns = current_user_ns(); + return get_user_ns(ns); +} + +static const void *user_initial_ns(void) +{ + return &init_user_ns; +} + +static void user_put_ns(void *p) +{ + struct user_namespace *ns = p; + put_user_ns(ns); +} + +static bool user_current_may_mount(void) +{ + return ns_capable(current_user_ns(), CAP_SYS_ADMIN); +} + +static bool user_initial_ns_propagates(void) +{ + return true; +} + +const struct kobj_ns_type_operations user_ns_type_operations = { + .type = KOBJ_NS_TYPE_USER, + .current_may_mount = user_current_may_mount, + .grab_current_ns = user_grab_current_ns, + .initial_ns = user_initial_ns, + .drop_ns = user_put_ns, + .initial_ns_propagates = user_initial_ns_propagates, +}; + +static const void *block_class_user_namespace(struct device *dev) +{ + struct gendisk *disk; + + if (dev->type == &part_type) + disk = part_to_disk(dev_to_part(dev)); + else + disk = dev_to_disk(dev); + + return disk->user_ns; +} + +static void block_class_get_ownership(struct device *dev, kuid_t *uid, kgid_t *gid) +{ + struct gendisk *disk; + struct user_namespace *ns; + + if (dev->type == &part_type) + disk = part_to_disk(dev_to_part(dev)); + else + disk = dev_to_disk(dev); + + ns = disk->user_ns; + if (ns && ns != &init_user_ns) { + kuid_t ns_root_uid = make_kuid(ns, 0); + kgid_t ns_root_gid = make_kgid(ns, 0); + + if (uid_valid(ns_root_uid)) + *uid = ns_root_uid; + + if (gid_valid(ns_root_gid)) + *gid = ns_root_gid; + } +} +#endif /* CONFIG_BLK_DEV_USER_NS */ + static int __init genhd_device_init(void) { int error; block_class.dev_kobj = sysfs_dev_block_kobj; +#ifdef CONFIG_BLK_DEV_USER_NS + kobj_ns_type_register(&user_ns_type_operations); +#endif error = class_register(&block_class); if (unlikely(error)) return error; @@ -1129,8 +1205,14 @@ static void disk_release(struct device *dev) blk_put_queue(disk->queue); kfree(disk); } + struct class block_class = { .name = "block", +#ifdef CONFIG_BLK_DEV_USER_NS + .ns_type = &user_ns_type_operations, + .namespace = block_class_user_namespace, + .get_ownership = block_class_get_ownership, +#endif }; static char *block_devnode(struct device *dev, umode_t *mode, @@ -1304,6 +1386,9 @@ struct gendisk *__alloc_disk_node(int minors, int node_id) disk_to_dev(disk)->class = &block_class; disk_to_dev(disk)->type = &disk_type; device_initialize(disk_to_dev(disk)); +#ifdef CONFIG_BLK_DEV_USER_NS + disk->user_ns = &init_user_ns; +#endif return disk; out_destroy_part_tbl: diff --git a/include/linux/genhd.h b/include/linux/genhd.h index 6fc26f7bdf71e..ba47fc047b03d 100644 --- a/include/linux/genhd.h +++ b/include/linux/genhd.h @@ -167,6 +167,9 @@ struct gendisk { int node_id; struct badblocks *bb; struct lockdep_map lockdep_map; +#ifdef CONFIG_BLK_DEV_USER_NS + struct user_namespace *user_ns; +#endif }; /* |
