diff options
-rw-r--r-- | block/genhd.c | 3 | ||||
-rw-r--r-- | drivers/base/core.c | 17 | ||||
-rw-r--r-- | drivers/base/devtmpfs.c | 27 | ||||
-rw-r--r-- | drivers/usb/core/usb.c | 3 | ||||
-rw-r--r-- | include/linux/device.h | 7 |
5 files changed, 39 insertions, 18 deletions
diff --git a/block/genhd.c b/block/genhd.c index 3c001fba80c7..dfcec431ceea 100644 --- a/block/genhd.c +++ b/block/genhd.c | |||
@@ -1111,7 +1111,8 @@ struct class block_class = { | |||
1111 | .name = "block", | 1111 | .name = "block", |
1112 | }; | 1112 | }; |
1113 | 1113 | ||
1114 | static char *block_devnode(struct device *dev, umode_t *mode) | 1114 | static char *block_devnode(struct device *dev, umode_t *mode, |
1115 | uid_t *uid, gid_t *gid) | ||
1115 | { | 1116 | { |
1116 | struct gendisk *disk = dev_to_disk(dev); | 1117 | struct gendisk *disk = dev_to_disk(dev); |
1117 | 1118 | ||
diff --git a/drivers/base/core.c b/drivers/base/core.c index a7391a30cb29..8a428b51089d 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c | |||
@@ -283,15 +283,21 @@ static int dev_uevent(struct kset *kset, struct kobject *kobj, | |||
283 | const char *tmp; | 283 | const char *tmp; |
284 | const char *name; | 284 | const char *name; |
285 | umode_t mode = 0; | 285 | umode_t mode = 0; |
286 | uid_t uid = 0; | ||
287 | gid_t gid = 0; | ||
286 | 288 | ||
287 | add_uevent_var(env, "MAJOR=%u", MAJOR(dev->devt)); | 289 | add_uevent_var(env, "MAJOR=%u", MAJOR(dev->devt)); |
288 | add_uevent_var(env, "MINOR=%u", MINOR(dev->devt)); | 290 | add_uevent_var(env, "MINOR=%u", MINOR(dev->devt)); |
289 | name = device_get_devnode(dev, &mode, &tmp); | 291 | name = device_get_devnode(dev, &mode, &uid, &gid, &tmp); |
290 | if (name) { | 292 | if (name) { |
291 | add_uevent_var(env, "DEVNAME=%s", name); | 293 | add_uevent_var(env, "DEVNAME=%s", name); |
292 | kfree(tmp); | ||
293 | if (mode) | 294 | if (mode) |
294 | add_uevent_var(env, "DEVMODE=%#o", mode & 0777); | 295 | add_uevent_var(env, "DEVMODE=%#o", mode & 0777); |
296 | if (uid) | ||
297 | add_uevent_var(env, "DEVUID=%u", uid); | ||
298 | if (gid) | ||
299 | add_uevent_var(env, "DEVGID=%u", gid); | ||
300 | kfree(tmp); | ||
295 | } | 301 | } |
296 | } | 302 | } |
297 | 303 | ||
@@ -1281,6 +1287,8 @@ static struct device *next_device(struct klist_iter *i) | |||
1281 | * device_get_devnode - path of device node file | 1287 | * device_get_devnode - path of device node file |
1282 | * @dev: device | 1288 | * @dev: device |
1283 | * @mode: returned file access mode | 1289 | * @mode: returned file access mode |
1290 | * @uid: returned file owner | ||
1291 | * @gid: returned file group | ||
1284 | * @tmp: possibly allocated string | 1292 | * @tmp: possibly allocated string |
1285 | * | 1293 | * |
1286 | * Return the relative path of a possible device node. | 1294 | * Return the relative path of a possible device node. |
@@ -1289,7 +1297,8 @@ static struct device *next_device(struct klist_iter *i) | |||
1289 | * freed by the caller. | 1297 | * freed by the caller. |
1290 | */ | 1298 | */ |
1291 | const char *device_get_devnode(struct device *dev, | 1299 | const char *device_get_devnode(struct device *dev, |
1292 | umode_t *mode, const char **tmp) | 1300 | umode_t *mode, uid_t *uid, gid_t *gid, |
1301 | const char **tmp) | ||
1293 | { | 1302 | { |
1294 | char *s; | 1303 | char *s; |
1295 | 1304 | ||
@@ -1297,7 +1306,7 @@ const char *device_get_devnode(struct device *dev, | |||
1297 | 1306 | ||
1298 | /* the device type may provide a specific name */ | 1307 | /* the device type may provide a specific name */ |
1299 | if (dev->type && dev->type->devnode) | 1308 | if (dev->type && dev->type->devnode) |
1300 | *tmp = dev->type->devnode(dev, mode); | 1309 | *tmp = dev->type->devnode(dev, mode, uid, gid); |
1301 | if (*tmp) | 1310 | if (*tmp) |
1302 | return *tmp; | 1311 | return *tmp; |
1303 | 1312 | ||
diff --git a/drivers/base/devtmpfs.c b/drivers/base/devtmpfs.c index 01fc5b07f951..fda52563677f 100644 --- a/drivers/base/devtmpfs.c +++ b/drivers/base/devtmpfs.c | |||
@@ -41,6 +41,8 @@ static struct req { | |||
41 | int err; | 41 | int err; |
42 | const char *name; | 42 | const char *name; |
43 | umode_t mode; /* 0 => delete */ | 43 | umode_t mode; /* 0 => delete */ |
44 | uid_t uid; | ||
45 | gid_t gid; | ||
44 | struct device *dev; | 46 | struct device *dev; |
45 | } *requests; | 47 | } *requests; |
46 | 48 | ||
@@ -85,7 +87,9 @@ int devtmpfs_create_node(struct device *dev) | |||
85 | return 0; | 87 | return 0; |
86 | 88 | ||
87 | req.mode = 0; | 89 | req.mode = 0; |
88 | req.name = device_get_devnode(dev, &req.mode, &tmp); | 90 | req.uid = 0; |
91 | req.gid = 0; | ||
92 | req.name = device_get_devnode(dev, &req.mode, &req.uid, &req.gid, &tmp); | ||
89 | if (!req.name) | 93 | if (!req.name) |
90 | return -ENOMEM; | 94 | return -ENOMEM; |
91 | 95 | ||
@@ -121,7 +125,7 @@ int devtmpfs_delete_node(struct device *dev) | |||
121 | if (!thread) | 125 | if (!thread) |
122 | return 0; | 126 | return 0; |
123 | 127 | ||
124 | req.name = device_get_devnode(dev, NULL, &tmp); | 128 | req.name = device_get_devnode(dev, NULL, NULL, NULL, &tmp); |
125 | if (!req.name) | 129 | if (!req.name) |
126 | return -ENOMEM; | 130 | return -ENOMEM; |
127 | 131 | ||
@@ -187,7 +191,8 @@ static int create_path(const char *nodepath) | |||
187 | return err; | 191 | return err; |
188 | } | 192 | } |
189 | 193 | ||
190 | static int handle_create(const char *nodename, umode_t mode, struct device *dev) | 194 | static int handle_create(const char *nodename, umode_t mode, uid_t uid, |
195 | gid_t gid, struct device *dev) | ||
191 | { | 196 | { |
192 | struct dentry *dentry; | 197 | struct dentry *dentry; |
193 | struct path path; | 198 | struct path path; |
@@ -201,14 +206,14 @@ static int handle_create(const char *nodename, umode_t mode, struct device *dev) | |||
201 | if (IS_ERR(dentry)) | 206 | if (IS_ERR(dentry)) |
202 | return PTR_ERR(dentry); | 207 | return PTR_ERR(dentry); |
203 | 208 | ||
204 | err = vfs_mknod(path.dentry->d_inode, | 209 | err = vfs_mknod(path.dentry->d_inode, dentry, mode, dev->devt); |
205 | dentry, mode, dev->devt); | ||
206 | if (!err) { | 210 | if (!err) { |
207 | struct iattr newattrs; | 211 | struct iattr newattrs; |
208 | 212 | ||
209 | /* fixup possibly umasked mode */ | ||
210 | newattrs.ia_mode = mode; | 213 | newattrs.ia_mode = mode; |
211 | newattrs.ia_valid = ATTR_MODE; | 214 | newattrs.ia_uid = uid; |
215 | newattrs.ia_gid = gid; | ||
216 | newattrs.ia_valid = ATTR_MODE|ATTR_UID|ATTR_GID; | ||
212 | mutex_lock(&dentry->d_inode->i_mutex); | 217 | mutex_lock(&dentry->d_inode->i_mutex); |
213 | notify_change(dentry, &newattrs); | 218 | notify_change(dentry, &newattrs); |
214 | mutex_unlock(&dentry->d_inode->i_mutex); | 219 | mutex_unlock(&dentry->d_inode->i_mutex); |
@@ -358,10 +363,11 @@ int devtmpfs_mount(const char *mntdir) | |||
358 | 363 | ||
359 | static DECLARE_COMPLETION(setup_done); | 364 | static DECLARE_COMPLETION(setup_done); |
360 | 365 | ||
361 | static int handle(const char *name, umode_t mode, struct device *dev) | 366 | static int handle(const char *name, umode_t mode, uid_t uid, gid_t gid, |
367 | struct device *dev) | ||
362 | { | 368 | { |
363 | if (mode) | 369 | if (mode) |
364 | return handle_create(name, mode, dev); | 370 | return handle_create(name, mode, uid, gid, dev); |
365 | else | 371 | else |
366 | return handle_remove(name, dev); | 372 | return handle_remove(name, dev); |
367 | } | 373 | } |
@@ -387,7 +393,8 @@ static int devtmpfsd(void *p) | |||
387 | spin_unlock(&req_lock); | 393 | spin_unlock(&req_lock); |
388 | while (req) { | 394 | while (req) { |
389 | struct req *next = req->next; | 395 | struct req *next = req->next; |
390 | req->err = handle(req->name, req->mode, req->dev); | 396 | req->err = handle(req->name, req->mode, |
397 | req->uid, req->gid, req->dev); | ||
391 | complete(&req->done); | 398 | complete(&req->done); |
392 | req = next; | 399 | req = next; |
393 | } | 400 | } |
diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c index f81b92572735..17002832abd9 100644 --- a/drivers/usb/core/usb.c +++ b/drivers/usb/core/usb.c | |||
@@ -317,7 +317,8 @@ static const struct dev_pm_ops usb_device_pm_ops = { | |||
317 | #endif /* CONFIG_PM */ | 317 | #endif /* CONFIG_PM */ |
318 | 318 | ||
319 | 319 | ||
320 | static char *usb_devnode(struct device *dev, umode_t *mode) | 320 | static char *usb_devnode(struct device *dev, |
321 | umode_t *mode, uid_t *uid, gid_t *gid) | ||
321 | { | 322 | { |
322 | struct usb_device *usb_dev; | 323 | struct usb_device *usb_dev; |
323 | 324 | ||
diff --git a/include/linux/device.h b/include/linux/device.h index 4a7c4a84afee..851b85c7101e 100644 --- a/include/linux/device.h +++ b/include/linux/device.h | |||
@@ -25,6 +25,7 @@ | |||
25 | #include <linux/pm.h> | 25 | #include <linux/pm.h> |
26 | #include <linux/atomic.h> | 26 | #include <linux/atomic.h> |
27 | #include <linux/ratelimit.h> | 27 | #include <linux/ratelimit.h> |
28 | #include <linux/uidgid.h> | ||
28 | #include <asm/device.h> | 29 | #include <asm/device.h> |
29 | 30 | ||
30 | struct device; | 31 | struct device; |
@@ -465,7 +466,8 @@ struct device_type { | |||
465 | const char *name; | 466 | const char *name; |
466 | const struct attribute_group **groups; | 467 | const struct attribute_group **groups; |
467 | int (*uevent)(struct device *dev, struct kobj_uevent_env *env); | 468 | int (*uevent)(struct device *dev, struct kobj_uevent_env *env); |
468 | char *(*devnode)(struct device *dev, umode_t *mode); | 469 | char *(*devnode)(struct device *dev, umode_t *mode, |
470 | uid_t *uid, gid_t *gid); | ||
469 | void (*release)(struct device *dev); | 471 | void (*release)(struct device *dev); |
470 | 472 | ||
471 | const struct dev_pm_ops *pm; | 473 | const struct dev_pm_ops *pm; |
@@ -843,7 +845,8 @@ extern int device_rename(struct device *dev, const char *new_name); | |||
843 | extern int device_move(struct device *dev, struct device *new_parent, | 845 | extern int device_move(struct device *dev, struct device *new_parent, |
844 | enum dpm_order dpm_order); | 846 | enum dpm_order dpm_order); |
845 | extern const char *device_get_devnode(struct device *dev, | 847 | extern const char *device_get_devnode(struct device *dev, |
846 | umode_t *mode, const char **tmp); | 848 | umode_t *mode, uid_t *uid, gid_t *gid, |
849 | const char **tmp); | ||
847 | extern void *dev_get_drvdata(const struct device *dev); | 850 | extern void *dev_get_drvdata(const struct device *dev); |
848 | extern int dev_set_drvdata(struct device *dev, void *data); | 851 | extern int dev_set_drvdata(struct device *dev, void *data); |
849 | 852 | ||