driver: core: add security labels to devtmpfs
Subsystems (23)
PATCH 2/3 driver: core: add security labels to devtmpfs
Add support for setting security labels(e.g. smack or selinux labels) to devtmpfs device nodes. In this manner, drivers can specify desired security label in their device_type->devnode or class->devnode method.
--- arch/x86/kernel/cpuid.c | 2 +- arch/x86/kernel/msr.c | 2 +- block/bsg.c | 2 +- block/genhd.c | 2 +- drivers/base/core.c | 9 +++++---- drivers/base/devtmpfs.c | 23 +++++++++++++++++------ drivers/block/aoe/aoechr.c | 2 +- drivers/block/pktcdvd.c | 2 +- drivers/char/mem.c | 2 +- drivers/char/misc.c | 2 +- drivers/char/raw.c | 2 +- drivers/char/tile-srom.c | 2 +- drivers/gpu/drm/drm_sysfs.c | 2 +- drivers/hid/usbhid/hiddev.c | 2 +- drivers/infiniband/core/cm.c | 2 +- drivers/infiniband/core/user_mad.c | 2 +- drivers/infiniband/core/uverbs_main.c | 2 +- drivers/input/input.c | 2 +- drivers/media/dvb-core/dvbdev.c | 2 +- drivers/media/pci/ddbridge/ddbridge-core.c | 2 +- drivers/misc/cxl/file.c | 2 +- drivers/s390/char/hmcdrv_dev.c | 2 +- drivers/tty/tty_io.c | 2 +- drivers/usb/class/usblp.c | 2 +- drivers/usb/core/file.c | 4 ++-- drivers/usb/core/usb.c | 3 ++- drivers/usb/misc/iowarrior.c | 2 +- drivers/usb/misc/legousbtower.c | 2 +- drivers/vfio/vfio.c | 2 +- fs/pstore/pmsg.c | 2 +- include/linux/device.h | 7 ++++--- include/linux/usb.h | 2 +- sound/sound_core.c | 2 +- 33 files changed, 58 insertions(+), 44 deletions(-)
arch/x86/kernel/cpuid.c +1 -1
@@ -176,7 +176,7 @@ static struct notifier_block __refdata cpuid_class_cpu_notifier = };static char *cpuid_devnode (struct device *dev,umode_t *mode, -kuid_t *uid,kgid_t *gid) +kuid_t *uid,kgid_t *gid,struct xattr *xattr) {return kasprintf (GFP_KERNEL ,"cpu/%u/cpuid" ,MINOR (dev->devt)); }
arch/x86/kernel/msr.c +1 -1
@@ -240,7 +240,7 @@ static struct notifier_block __refdata msr_class_cpu_notifier = { };static char *msr_devnode (struct device *dev,umode_t *mode, -kuid_t *uid,kgid_t *gid) +kuid_t *uid,kgid_t *gid,struct xattr *xattr) {return kasprintf (GFP_KERNEL ,"cpu/%u/msr" ,MINOR (dev->devt)); }
block/bsg.c +1 -1
@@ -1041,7 +1041,7 @@ EXPORT_SYMBOL_GPL(bsg_register_queue);static struct cdev bsg_cdev;static char *bsg_devnode (struct device *dev,umode_t *mode, -kuid_t *uid,kgid_t *gid) +kuid_t *uid,kgid_t *gid,struct xattr *xattr) {return kasprintf (GFP_KERNEL ,"bsg/%s" ,dev_name (dev)); }
block/genhd.c +1 -1
@@ -1121,7 +1121,7 @@ struct class block_class = { };static char *block_devnode (struct device *dev,umode_t *mode, -kuid_t *uid,kgid_t *gid) +kuid_t *uid,kgid_t *gid,struct xattr *xattr) {struct gendisk *disk =dev_to_disk (dev);
drivers/base/core.c +5 -4
@@ -311,7 +311,7 @@ static int dev_uevent(struct kset *kset, struct kobject *kobj,add_uevent_var (env,"MAJOR=%u" ,MAJOR (dev->devt));add_uevent_var (env,"MINOR=%u" ,MINOR (dev->devt)); - name =device_get_devnode (dev, &mode, &uid, &gid, &tmp); + name =device_get_devnode (dev, &mode, &uid, &gid,NULL , &tmp);if (name) {add_uevent_var (env,"DEVNAME=%s" , name);if (mode)
@@ -1271,6 +1271,7 @@ static struct device *next_device(struct klist_iter *i)* @mode: returned file access mode * @uid: returned file owner * @gid: returned file group +* @xattr: returned file xattr * @tmp: possibly allocated string * * Return the relative path of a possible device node.
@@ -1280,7 +1281,7 @@ static struct device *next_device(struct klist_iter *i)*/ const char *device_get_devnode (struct device *dev,umode_t *mode,kuid_t *uid,kgid_t *gid, -const char **tmp) +struct xattr *xattr,const char **tmp) {char *s;
@@ -1288,13 +1289,13 @@ const char *device_get_devnode(struct device *dev,/* the device type may provide a specific name */ if (dev->type && dev->type->devnode) - *tmp = dev->type->devnode (dev, mode, uid, gid); + *tmp = dev->type->devnode (dev, mode, uid, gid, xattr);if (*tmp)return *tmp;/* the class may provide a specific name */ if (dev->class && dev->class->devnode) - *tmp = dev->class->devnode (dev, mode, uid, gid); + *tmp = dev->class->devnode (dev, mode, uid, gid, xattr);if (*tmp)return *tmp;
drivers/base/devtmpfs.c +17 -6
@@ -44,6 +44,7 @@ static struct req {umode_t mode;/* 0 => delete */ kuid_t uid;kgid_t gid; +struct xattr xattr;struct device *dev; } *requests;
@@ -90,7 +91,12 @@ int devtmpfs_create_node(struct device *dev) req.mode =0 ; req.uid =GLOBAL_ROOT_UID ; req.gid =GLOBAL_ROOT_GID ; - req.name =device_get_devnode (dev, &req.mode, &req.uid, &req.gid, &tmp); + req.xattr.value =kmalloc (XATTR_SIZE_MAX ,GFP_KERNEL ); +if (!req.xattr.value) +return -ENOMEM ; + req.xattr.value_len =0 ; + req.name =device_get_devnode (dev, &req.mode, &req.uid, &req.gid, + &req.xattr, &tmp);if (!req.name)return -ENOMEM ;
@@ -113,6 +119,7 @@ int devtmpfs_create_node(struct device *dev)wake_up_process (thread);wait_for_completion (&req.done); +kfree (req.xattr.value);kfree (tmp);return req.err;
@@ -126,7 +133,7 @@ int devtmpfs_delete_node(struct device *dev)if (!thread)return 0 ; - req.name =device_get_devnode (dev,NULL ,NULL ,NULL , &tmp); + req.name =device_get_devnode (dev,NULL ,NULL ,NULL ,NULL , &tmp);if (!req.name)return -ENOMEM ;
@@ -193,7 +200,7 @@ static int create_path(const char *nodepath) }static int handle_create (const char *nodename,umode_t mode,kuid_t uid, -kgid_t gid,struct device *dev) +kgid_t gid,struct xattr xattr,struct device *dev) {struct dentry *dentry;struct path path;
@@ -221,6 +228,9 @@ static int handle_create(const char *nodename, umode_t mode, kuid_t uid,/* mark as kernel-created inode */ d_inode (dentry)->i_private = &thread; +if (xattr.value_len >0 ) +vfs_setxattr (dentry, xattr.name, xattr.value, + xattr.value_len,0 ); }done_path_create (&path, dentry);return err;
@@ -365,10 +375,10 @@ int devtmpfs_mount(const char *mntdir)static DECLARE_COMPLETION (setup_done);static int handle (const char *name,umode_t mode,kuid_t uid,kgid_t gid, -struct device *dev) +struct xattr xattr,struct device *dev) {if (mode) -return handle_create (name, mode, uid, gid, dev); +return handle_create (name, mode, uid, gid, xattr, dev);else return handle_remove (name, dev); }
@@ -395,7 +405,8 @@ static int devtmpfsd(void *p)while (req) {struct req *next = req->next; req->err =handle (req->name, req->mode, - req->uid, req->gid, req->dev); + req->uid, req->gid, + req->xattr, req->dev);complete (&req->done); req = next; }
drivers/block/aoe/aoechr.c +1 -1
@@ -276,7 +276,7 @@ static const struct file_operations aoe_fops = { };static char *aoe_devnode (struct device *dev,umode_t *mode, -kuid_t *uid,kgid_t *gid) +kuid_t *uid,kgid_t *gid,struct xattr *xattr) {return kasprintf (GFP_KERNEL ,"etherd/%s" ,dev_name (dev)); }
drivers/block/pktcdvd.c +1 -1
@@ -2732,7 +2732,7 @@ static const struct block_device_operations pktcdvd_ops = { };static char *pktcdvd_devnode (struct gendisk *gd,umode_t *mode, -kuid_t *uid,kgid_t *gid) +kuid_t *uid,kgid_t *gid,struct xattr *xattr) {return kasprintf (GFP_KERNEL ,"pktcdvd/%s" , gd->disk_name); }
drivers/char/mem.c +1 -1
@@ -832,7 +832,7 @@ static const struct file_operations memory_fops = { };static char *mem_devnode (struct device *dev,umode_t *mode, -kuid_t *uid,kgid_t *gid) +kuid_t *uid,kgid_t *gid,struct xattr *xattr) {if (mode && devlist[MINOR (dev->devt)].mode) *mode = devlist[MINOR (dev->devt)].mode;
drivers/char/misc.c +1 -1
@@ -268,7 +268,7 @@ EXPORT_SYMBOL(misc_register);EXPORT_SYMBOL (misc_deregister);static char *misc_devnode (struct device *dev,umode_t *mode, -kuid_t *uid,kgid_t *gid) +kuid_t *uid,kgid_t *gid,struct xattr *xattr) {struct miscdevice *c =dev_get_drvdata (dev);
drivers/char/raw.c +1 -1
@@ -306,7 +306,7 @@ static const struct file_operations raw_ctl_fops = {static struct cdev raw_cdev;static char *raw_devnode (struct device *dev,umode_t *mode, -kuid_t *uid,kgid_t *gid) +kuid_t *uid,kgid_t *gid,struct xattr *xattr) {return kasprintf (GFP_KERNEL ,"raw/%s" ,dev_name (dev)); }
drivers/char/tile-srom.c +1 -1
@@ -311,7 +311,7 @@ static struct attribute *srom_dev_attrs[] = {ATTRIBUTE_GROUPS (srom_dev);static char *srom_devnode (struct device *dev,umode_t *mode, -kuid_t *uid,kgid_t *gid) +kuid_t *uid,kgid_t *gid,struct xattr *xattr) { *mode =S_IRUGO |S_IWUSR ;return kasprintf (GFP_KERNEL ,"srom/%s" ,dev_name (dev));
drivers/gpu/drm/drm_sysfs.c +1 -1
@@ -100,7 +100,7 @@ static const struct dev_pm_ops drm_class_dev_pm_ops = { };static char *drm_devnode (struct device *dev,umode_t *mode, -kuid_t *uid,kgid_t *gid) +kuid_t *uid,kgid_t *gid,struct xattr *xattr) {return kasprintf (GFP_KERNEL ,"dri/%s" ,dev_name (dev)); }
drivers/hid/usbhid/hiddev.c +1 -1
@@ -861,7 +861,7 @@ static const struct file_operations hiddev_fops = { };static char *hiddev_devnode (struct device *dev,umode_t *mode, -kuid_t *uid,kgid_t *gid) +kuid_t *uid,kgid_t *gid,struct xattr *xattr) {return kasprintf (GFP_KERNEL ,"usb/%s" ,dev_name (dev)); }
drivers/infiniband/core/cm.c +1 -1
@@ -3692,7 +3692,7 @@ static struct kobj_type cm_port_obj_type = { };static char *cm_devnode (struct device *dev,umode_t *mode, -kuid_t *uid,kgid_t *gid) +kuid_t *uid,kgid_t *gid,struct xattr *xattr) {if (mode) *mode =0666 ;
drivers/infiniband/core/user_mad.c +1 -1
@@ -1333,7 +1333,7 @@ static void ib_umad_remove_one(struct ib_device *device) }static char *umad_devnode (struct device *dev,umode_t *mode, -kuid_t *uid,kgid_t *gid) +kuid_t *uid,kgid_t *gid,struct xattr *xattr) {return kasprintf (GFP_KERNEL ,"infiniband/%s" ,dev_name (dev)); }
drivers/infiniband/core/uverbs_main.c +1 -1
@@ -969,7 +969,7 @@ static void ib_uverbs_remove_one(struct ib_device *device) }static char *uverbs_devnode (struct device *dev,umode_t *mode, -kuid_t *uid,kgid_t *gid) +kuid_t *uid,kgid_t *gid,struct xattr *xattr) {if (mode) *mode =0666 ;
drivers/input/input.c +1 -1
@@ -1760,7 +1760,7 @@ static struct device_type input_dev_type = { };static char *input_devnode (struct device *dev,umode_t *mode, -kuid_t *uid,kgid_t *gid) +kuid_t *uid,kgid_t *gid,struct xattr *xattr) {return kasprintf (GFP_KERNEL ,"input/%s" ,dev_name (dev)); }
drivers/media/dvb-core/dvbdev.c +1 -1
@@ -585,7 +585,7 @@ static int dvb_uevent(struct device *dev, struct kobj_uevent_env *env) }static char *dvb_devnode (struct device *dev,umode_t *mode, -kuid_t *uid,kgid_t *gid) +kuid_t *uid,kgid_t *gid,struct xattr *xattr) {struct dvb_device *dvbdev =dev_get_drvdata (dev);
drivers/media/pci/ddbridge/ddbridge-core.c +1 -1
@@ -1477,7 +1477,7 @@ static const struct file_operations ddb_fops = { };static char *ddb_devnode (struct device *device,umode_t *mode, -kuid_t *uid,kgid_t *gid) +kuid_t *uid,kgid_t *gid,struct xattr *xattr) {struct ddb *dev =dev_get_drvdata (device);
drivers/misc/cxl/file.c +1 -1
@@ -409,7 +409,7 @@ const struct file_operations afu_master_fops = {static char *cxl_devnode (struct device *dev,umode_t *mode, -kuid_t *uid,kgid_t *gid) +kuid_t *uid,kgid_t *gid,struct xattr *xattr) {if (CXL_DEVT_IS_CARD (dev->devt)) {/*
drivers/s390/char/hmcdrv_dev.c +1 -1
@@ -90,7 +90,7 @@ static dev_t hmcdrv_dev_no; /* device number (major/minor) */* Return: recommended device file name in /dev */ static char *hmcdrv_dev_name (struct device *dev,umode_t *mode, -kuid_t *uid,kgid_t *gid) +kuid_t *uid,kgid_t *gid,struct xattr *xattr) {char *nodename =NULL ;const char *devname =dev_name (dev);/* kernel device name */
drivers/tty/tty_io.c +1 -1
@@ -3529,7 +3529,7 @@ void __init console_init(void) }static char *tty_devnode (struct device *dev,umode_t *mode, -kuid_t *uid,kgid_t *gid) +kuid_t *uid,kgid_t *gid,struct xattr *xattr) {if (!mode)return NULL ;
drivers/usb/class/usblp.c +1 -1
@@ -1059,7 +1059,7 @@ static const struct file_operations usblp_fops = { };static char *usblp_devnode (struct device *dev,umode_t *mode, -kuid_t *uid,kgid_t *gid) +kuid_t *uid,kgid_t *gid,struct xattr *xattr) {return kasprintf (GFP_KERNEL ,"usb/%s" ,dev_name (dev)); }
drivers/usb/core/file.c +2 -2
@@ -59,14 +59,14 @@ static struct usb_class { } *usb_class;static char *usb_devnode (struct device *dev,umode_t *mode, -kuid_t *uid,kgid_t *gid) +kuid_t *uid,kgid_t *gid,struct xattr *xattr) {struct usb_class_driver *drv; drv =dev_get_drvdata (dev);if (!drv || !drv->devnode)return NULL ; -return drv->devnode (dev, mode, uid, gid); +return drv->devnode (dev, mode, uid, gid, xattr); }static int init_usb_class (void )
drivers/usb/core/usb.c +2 -1
@@ -373,7 +373,8 @@ static const struct dev_pm_ops usb_device_pm_ops = {static char *usb_devnode (struct device *dev, -umode_t *mode,kuid_t *uid,kgid_t *gid) +umode_t *mode,kuid_t *uid,kgid_t *gid, +struct xattr *xattr) {struct usb_device *usb_dev;
drivers/usb/misc/iowarrior.c +1 -1
@@ -730,7 +730,7 @@ static const struct file_operations iowarrior_fops = { };static char *iowarrior_devnode (struct device *dev,umode_t *mode, -kuid_t *uid,kgid_t *gid) +kuid_t *uid,kgid_t *gid,struct xattr *xattr) {return kasprintf (GFP_KERNEL ,"usb/%s" ,dev_name (dev)); }
drivers/usb/misc/legousbtower.c +1 -1
@@ -254,7 +254,7 @@ static const struct file_operations tower_fops = { };static char *legousbtower_devnode (struct device *dev,umode_t *mode, -kuid_t *uid,kgid_t *gid) +kuid_t *uid,kgid_t *gid,struct xattr *xattr) {return kasprintf (GFP_KERNEL ,"usb/%s" ,dev_name (dev)); }
drivers/vfio/vfio.c +1 -1
@@ -1520,7 +1520,7 @@ EXPORT_SYMBOL_GPL(vfio_external_check_extension);* Module/class support */ static char *vfio_devnode (struct device *dev,umode_t *mode, -kuid_t *uid,kgid_t *gid) +kuid_t *uid,kgid_t *gid,struct xattr *xattr) {return kasprintf (GFP_KERNEL ,"vfio/%s" ,dev_name (dev)); }
fs/pstore/pmsg.c +1 -1
@@ -74,7 +74,7 @@ static int pmsg_major;#define pr_fmt (fmt) PMSG_NAME ": " fmtstatic char *pmsg_devnode (struct device *dev,umode_t *mode, -kuid_t *uid,kgid_t *gid) +kuid_t *uid,kgid_t *gid,struct xattr *xattr) {if (mode) *mode =0220 ;
include/linux/device.h +4 -3
@@ -27,6 +27,7 @@#include <linux/ratelimit.h> #include <linux/uidgid.h> #include <linux/gfp.h> +#include <linux/xattr.h> #include <asm/device.h> struct device ;
@@ -390,7 +391,7 @@ struct class {int (*dev_uevent)(struct device *dev,struct kobj_uevent_env *env);char *(*devnode)(struct device *dev,umode_t *mode, -kuid_t *uid,kgid_t *gid); +kuid_t *uid,kgid_t *gid,struct xattr *xattr);void (*class_release)(struct class *class);void (*dev_release)(struct device *dev);
@@ -535,7 +536,7 @@ struct device_type {const struct attribute_group **groups;int (*uevent)(struct device *dev,struct kobj_uevent_env *env);char *(*devnode)(struct device *dev,umode_t *mode, -kuid_t *uid,kgid_t *gid); +kuid_t *uid,kgid_t *gid,struct xattr *xattr);void (*release)(struct device *dev);const struct dev_pm_ops *pm;
@@ -966,7 +967,7 @@ extern int device_move(struct device *dev, struct device *new_parent, enum dpm_order dpm_order);extern const char *device_get_devnode (struct device *dev,umode_t *mode,kuid_t *uid,kgid_t *gid, -const char **tmp); +struct xattr *xattr,const char **tmp);static inline bool device_supports_offline (struct device *dev) {
include/linux/usb.h +1 -1
@@ -1158,7 +1158,7 @@ extern struct bus_type usb_bus_type;struct usb_class_driver {char *name;char *(*devnode)(struct device *dev,umode_t *mode, -kuid_t *uid,kgid_t *gid); +kuid_t *uid,kgid_t *gid,struct xattr *xattr);const struct file_operations *fops;int minor_base; };
sound/sound_core.c +1 -1
@@ -30,7 +30,7 @@ MODULE_AUTHOR("Alan Cox");MODULE_LICENSE ("GPL" );static char *sound_devnode (struct device *dev,umode_t *mode, -kuid_t *uid,kgid_t *gid) +kuid_t *uid,kgid_t *gid,struct xattr *xattr) {if (MAJOR (dev->devt) ==SOUND_MAJOR )return NULL ;
Signature · 1 line
1.8.5.5
'Greg Kroah-Hartman'
maintainerQuoted 3 lines · Namjae Jeon
Add support for setting security labels(e.g. smack or selinux labels) to devtmpfs device nodes. In this manner, drivers can specify desired security label in their
device_type->devnodeorclass->devnodemethod.
What driver wants to do this? And how does it determine the proper security label from within the kernel? Isn't that something that only userspace can know/set properly?
thanks,
greg k-h
Quoted 8 lines · Namjae Jeon
Quoted 3 lines
Add support for setting security labels(e.g. smack or selinux labels) to devtmpfs device nodes. In this manner, drivers can specify desired security label in their
device_type->devnodeorclass->devnodemethod.What driver wants to do this? And how does it determine the proper security label from within the kernel? Isn't that something that only userspace can know/set properly?
Yes, It is possible by userspace, But This api change will help to set uid/gid and xattr values easily without need of complex userspace scripts in absence of udev like helper.
And security label that decided as per each embedded system will be set by this api in driver.
Quoted 4 lines
thanks,
greg k-h
'Greg Kroah-Hartman'
maintainerQuoted 11 lines · Namjae Jeon
Quoted 8 lines · Namjae Jeon
Quoted 3 lines
Add support for setting security labels(e.g. smack or selinux labels) to devtmpfs device nodes. In this manner, drivers can specify desired security label in their
device_type->devnodeorclass->devnodemethod.What driver wants to do this? And how does it determine the proper security label from within the kernel? Isn't that something that only userspace can know/set properly?
Yes, It is possible by userspace, But This api change will help to set uid/gid and xattr values easily without need of complex userspace scripts in absence of udev like helper.
If you want to do things like this, use a "complex" userspace script like Android has for their startup (hint, it's just a tiny bash script, nothing "complex" about it at all...)
Quoted 2 lines
And security label that decided as per each embedded system will be set by this api in driver.
Exactly how will that happen? I don't see any users of it.
greg k-h