Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

driver core: handle user namespaces properly with the uid/gid devtmpfs change

Now that devtmpfs is caring about uid/gid, we need to use the correct
internal types so users who have USER_NS enabled will have things work
properly for them.

Thanks to Eric for pointing this out, and the patch review.

Reported-by: Eric W. Biederman <ebiederm@xmission.com>
Cc: Kay Sievers <kay@vrfy.org>
Cc: Ming Lei <ming.lei@canonical.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

+20 -20
+1 -1
block/genhd.c
··· 1112 1112 }; 1113 1113 1114 1114 static char *block_devnode(struct device *dev, umode_t *mode, 1115 - uid_t *uid, gid_t *gid) 1115 + kuid_t *uid, kgid_t *gid) 1116 1116 { 1117 1117 struct gendisk *disk = dev_to_disk(dev); 1118 1118
+7 -7
drivers/base/core.c
··· 283 283 const char *tmp; 284 284 const char *name; 285 285 umode_t mode = 0; 286 - uid_t uid = 0; 287 - gid_t gid = 0; 286 + kuid_t uid = GLOBAL_ROOT_UID; 287 + kgid_t gid = GLOBAL_ROOT_GID; 288 288 289 289 add_uevent_var(env, "MAJOR=%u", MAJOR(dev->devt)); 290 290 add_uevent_var(env, "MINOR=%u", MINOR(dev->devt)); ··· 293 293 add_uevent_var(env, "DEVNAME=%s", name); 294 294 if (mode) 295 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); 296 + if (!uid_eq(uid, GLOBAL_ROOT_UID)) 297 + add_uevent_var(env, "DEVUID=%u", from_kuid(&init_user_ns, uid)); 298 + if (!gid_eq(gid, GLOBAL_ROOT_GID)) 299 + add_uevent_var(env, "DEVGID=%u", from_kgid(&init_user_ns, gid)); 300 300 kfree(tmp); 301 301 } 302 302 } ··· 1297 1297 * freed by the caller. 1298 1298 */ 1299 1299 const char *device_get_devnode(struct device *dev, 1300 - umode_t *mode, uid_t *uid, gid_t *gid, 1300 + umode_t *mode, kuid_t *uid, kgid_t *gid, 1301 1301 const char **tmp) 1302 1302 { 1303 1303 char *s;
+9 -9
drivers/base/devtmpfs.c
··· 42 42 int err; 43 43 const char *name; 44 44 umode_t mode; /* 0 => delete */ 45 - uid_t uid; 46 - gid_t gid; 45 + kuid_t uid; 46 + kgid_t gid; 47 47 struct device *dev; 48 48 } *requests; 49 49 ··· 88 88 return 0; 89 89 90 90 req.mode = 0; 91 - req.uid = 0; 92 - req.gid = 0; 91 + req.uid = GLOBAL_ROOT_UID; 92 + req.gid = GLOBAL_ROOT_GID; 93 93 req.name = device_get_devnode(dev, &req.mode, &req.uid, &req.gid, &tmp); 94 94 if (!req.name) 95 95 return -ENOMEM; ··· 192 192 return err; 193 193 } 194 194 195 - static int handle_create(const char *nodename, umode_t mode, uid_t uid, 196 - gid_t gid, struct device *dev) 195 + static int handle_create(const char *nodename, umode_t mode, kuid_t uid, 196 + kgid_t gid, struct device *dev) 197 197 { 198 198 struct dentry *dentry; 199 199 struct path path; ··· 212 212 struct iattr newattrs; 213 213 214 214 newattrs.ia_mode = mode; 215 - newattrs.ia_uid = KUIDT_INIT(uid); 216 - newattrs.ia_gid = KGIDT_INIT(gid); 215 + newattrs.ia_uid = uid; 216 + newattrs.ia_gid = gid; 217 217 newattrs.ia_valid = ATTR_MODE|ATTR_UID|ATTR_GID; 218 218 mutex_lock(&dentry->d_inode->i_mutex); 219 219 notify_change(dentry, &newattrs); ··· 364 364 365 365 static DECLARE_COMPLETION(setup_done); 366 366 367 - static int handle(const char *name, umode_t mode, uid_t uid, gid_t gid, 367 + static int handle(const char *name, umode_t mode, kuid_t uid, kgid_t gid, 368 368 struct device *dev) 369 369 { 370 370 if (mode)
+1 -1
drivers/usb/core/usb.c
··· 318 318 319 319 320 320 static char *usb_devnode(struct device *dev, 321 - umode_t *mode, uid_t *uid, gid_t *gid) 321 + umode_t *mode, kuid_t *uid, kgid_t *gid) 322 322 { 323 323 struct usb_device *usb_dev; 324 324
+2 -2
include/linux/device.h
··· 467 467 const struct attribute_group **groups; 468 468 int (*uevent)(struct device *dev, struct kobj_uevent_env *env); 469 469 char *(*devnode)(struct device *dev, umode_t *mode, 470 - uid_t *uid, gid_t *gid); 470 + kuid_t *uid, kgid_t *gid); 471 471 void (*release)(struct device *dev); 472 472 473 473 const struct dev_pm_ops *pm; ··· 845 845 extern int device_move(struct device *dev, struct device *new_parent, 846 846 enum dpm_order dpm_order); 847 847 extern const char *device_get_devnode(struct device *dev, 848 - umode_t *mode, uid_t *uid, gid_t *gid, 848 + umode_t *mode, kuid_t *uid, kgid_t *gid, 849 849 const char **tmp); 850 850 extern void *dev_get_drvdata(const struct device *dev); 851 851 extern int dev_set_drvdata(struct device *dev, void *data);