From 8c41f3b1fb98a30664c73d61745b346d4013ced5 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Sat, 22 Dec 2012 18:36:55 +0100 Subject: [PATCH] driver core: add uid and gid to devtmpfs --- block/genhd.c | 3 ++- drivers/base/core.c | 17 +++++++++++++---- drivers/base/devtmpfs.c | 27 +++++++++++++++++---------- drivers/usb/core/usb.c | 3 ++- include/linux/device.h | 7 +++++-- 5 files changed, 39 insertions(+), 18 deletions(-) --- a/block/genhd.c +++ b/block/genhd.c @@ -1107,7 +1107,8 @@ struct class block_class = { .name = "block", }; -static char *block_devnode(struct device *dev, umode_t *mode) +static char *block_devnode(struct device *dev, umode_t *mode, + uid_t *uid, gid_t *gid) { struct gendisk *disk = dev_to_disk(dev); --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -283,15 +283,21 @@ static int dev_uevent(struct kset *kset, const char *tmp; const char *name; umode_t mode = 0; + uid_t uid = 0; + gid_t gid = 0; add_uevent_var(env, "MAJOR=%u", MAJOR(dev->devt)); add_uevent_var(env, "MINOR=%u", MINOR(dev->devt)); - name = device_get_devnode(dev, &mode, &tmp); + name = device_get_devnode(dev, &mode, &uid, &gid, &tmp); if (name) { add_uevent_var(env, "DEVNAME=%s", name); - kfree(tmp); if (mode) add_uevent_var(env, "DEVMODE=%#o", mode & 0777); + if (uid) + add_uevent_var(env, "DEVUID=%u", uid); + if (gid) + add_uevent_var(env, "DEVGID=%u", gid); + kfree(tmp); } } @@ -1274,6 +1280,8 @@ static struct device *next_device(struct * device_get_devnode - path of device node file * @dev: device * @mode: returned file access mode + * @uid: returned file owner + * @gid: returned file group * @tmp: possibly allocated string * * Return the relative path of a possible device node. @@ -1282,7 +1290,8 @@ static struct device *next_device(struct * freed by the caller. */ const char *device_get_devnode(struct device *dev, - umode_t *mode, const char **tmp) + umode_t *mode, uid_t *uid, gid_t *gid, + const char **tmp) { char *s; @@ -1290,7 +1299,7 @@ const char *device_get_devnode(struct de /* the device type may provide a specific name */ if (dev->type && dev->type->devnode) - *tmp = dev->type->devnode(dev, mode); + *tmp = dev->type->devnode(dev, mode, uid, gid); if (*tmp) return *tmp; --- a/drivers/base/devtmpfs.c +++ b/drivers/base/devtmpfs.c @@ -41,6 +41,8 @@ static struct req { int err; const char *name; umode_t mode; /* 0 => delete */ + uid_t uid; + gid_t gid; struct device *dev; } *requests; @@ -85,7 +87,9 @@ int devtmpfs_create_node(struct device * return 0; req.mode = 0; - req.name = device_get_devnode(dev, &req.mode, &tmp); + req.uid = 0; + req.gid = 0; + req.name = device_get_devnode(dev, &req.mode, &req.uid, &req.gid, &tmp); if (!req.name) return -ENOMEM; @@ -121,7 +125,7 @@ int devtmpfs_delete_node(struct device * if (!thread) return 0; - req.name = device_get_devnode(dev, NULL, &tmp); + req.name = device_get_devnode(dev, NULL, NULL, NULL, &tmp); if (!req.name) return -ENOMEM; @@ -187,7 +191,8 @@ static int create_path(const char *nodep return err; } -static int handle_create(const char *nodename, umode_t mode, struct device *dev) +static int handle_create(const char *nodename, umode_t mode, uid_t uid, + gid_t gid, struct device *dev) { struct dentry *dentry; struct path path; @@ -201,14 +206,14 @@ static int handle_create(const char *nod if (IS_ERR(dentry)) return PTR_ERR(dentry); - err = vfs_mknod(path.dentry->d_inode, - dentry, mode, dev->devt); + err = vfs_mknod(path.dentry->d_inode, dentry, mode, dev->devt); if (!err) { struct iattr newattrs; - /* fixup possibly umasked mode */ newattrs.ia_mode = mode; - newattrs.ia_valid = ATTR_MODE; + newattrs.ia_uid = uid; + newattrs.ia_gid = gid; + newattrs.ia_valid = ATTR_MODE|ATTR_UID|ATTR_GID; mutex_lock(&dentry->d_inode->i_mutex); notify_change(dentry, &newattrs); mutex_unlock(&dentry->d_inode->i_mutex); @@ -357,10 +362,11 @@ int devtmpfs_mount(const char *mntdir) static DECLARE_COMPLETION(setup_done); -static int handle(const char *name, umode_t mode, struct device *dev) +static int handle(const char *name, umode_t mode, uid_t uid, gid_t gid, + struct device *dev) { if (mode) - return handle_create(name, mode, dev); + return handle_create(name, mode, uid, gid, dev); else return handle_remove(name, dev); } @@ -386,7 +392,8 @@ static int devtmpfsd(void *p) spin_unlock(&req_lock); while (req) { struct req *next = req->next; - req->err = handle(req->name, req->mode, req->dev); + req->err = handle(req->name, req->mode, + req->uid, req->gid, req->dev); complete(&req->done); req = next; } --- a/drivers/usb/core/usb.c +++ b/drivers/usb/core/usb.c @@ -317,7 +317,8 @@ static const struct dev_pm_ops usb_devic #endif /* CONFIG_PM */ -static char *usb_devnode(struct device *dev, umode_t *mode) +static char *usb_devnode(struct device *dev, + umode_t *mode, uid_t *uid, gid_t *gid) { struct usb_device *usb_dev; --- a/include/linux/device.h +++ b/include/linux/device.h @@ -24,6 +24,7 @@ #include #include #include +#include #include struct device; @@ -470,7 +471,8 @@ struct device_type { const char *name; const struct attribute_group **groups; int (*uevent)(struct device *dev, struct kobj_uevent_env *env); - char *(*devnode)(struct device *dev, umode_t *mode); + char *(*devnode)(struct device *dev, umode_t *mode, + uid_t *uid, gid_t *gid); void (*release)(struct device *dev); const struct dev_pm_ops *pm; @@ -841,7 +843,8 @@ extern int device_rename(struct device * 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, const char **tmp); + umode_t *mode, uid_t *uid, gid_t *gid, + const char **tmp); extern void *dev_get_drvdata(const struct device *dev); extern int dev_set_drvdata(struct device *dev, void *data);