aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/base
diff options
context:
space:
mode:
authorKay Sievers <kay.sievers@vrfy.org>2009-09-18 17:01:12 -0400
committerLive-CD User <linux@linux.site>2009-09-19 15:50:38 -0400
commite454cea20bdcff10ee698d11b8882662a0153a47 (patch)
treef44581fe57787aef0a4f4dc00993a90ea8e688f6 /drivers/base
parent78f28b7c555359c67c2a0d23f7436e915329421e (diff)
Driver-Core: extend devnode callbacks to provide permissions
This allows subsytems to provide devtmpfs with non-default permissions for the device node. Instead of the default mode of 0600, null, zero, random, urandom, full, tty, ptmx now have a mode of 0666, which allows non-privileged processes to access standard device nodes in case no other userspace process applies the expected permissions. This also fixes a wrong assignment in pktcdvd and a checkpatch.pl complain. Signed-off-by: Kay Sievers <kay.sievers@vrfy.org> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/base')
-rw-r--r--drivers/base/core.c19
-rw-r--r--drivers/base/devtmpfs.c24
2 files changed, 28 insertions, 15 deletions
diff --git a/drivers/base/core.c b/drivers/base/core.c
index 390e664ec1c7..6bee6af8d8e1 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -166,13 +166,16 @@ static int dev_uevent(struct kset *kset, struct kobject *kobj,
166 if (MAJOR(dev->devt)) { 166 if (MAJOR(dev->devt)) {
167 const char *tmp; 167 const char *tmp;
168 const char *name; 168 const char *name;
169 mode_t mode = 0;
169 170
170 add_uevent_var(env, "MAJOR=%u", MAJOR(dev->devt)); 171 add_uevent_var(env, "MAJOR=%u", MAJOR(dev->devt));
171 add_uevent_var(env, "MINOR=%u", MINOR(dev->devt)); 172 add_uevent_var(env, "MINOR=%u", MINOR(dev->devt));
172 name = device_get_nodename(dev, &tmp); 173 name = device_get_devnode(dev, &mode, &tmp);
173 if (name) { 174 if (name) {
174 add_uevent_var(env, "DEVNAME=%s", name); 175 add_uevent_var(env, "DEVNAME=%s", name);
175 kfree(tmp); 176 kfree(tmp);
177 if (mode)
178 add_uevent_var(env, "DEVMODE=%#o", mode & 0777);
176 } 179 }
177 } 180 }
178 181
@@ -1148,8 +1151,9 @@ static struct device *next_device(struct klist_iter *i)
1148} 1151}
1149 1152
1150/** 1153/**
1151 * device_get_nodename - path of device node file 1154 * device_get_devnode - path of device node file
1152 * @dev: device 1155 * @dev: device
1156 * @mode: returned file access mode
1153 * @tmp: possibly allocated string 1157 * @tmp: possibly allocated string
1154 * 1158 *
1155 * Return the relative path of a possible device node. 1159 * Return the relative path of a possible device node.
@@ -1157,21 +1161,22 @@ static struct device *next_device(struct klist_iter *i)
1157 * a name. This memory is returned in tmp and needs to be 1161 * a name. This memory is returned in tmp and needs to be
1158 * freed by the caller. 1162 * freed by the caller.
1159 */ 1163 */
1160const char *device_get_nodename(struct device *dev, const char **tmp) 1164const char *device_get_devnode(struct device *dev,
1165 mode_t *mode, const char **tmp)
1161{ 1166{
1162 char *s; 1167 char *s;
1163 1168
1164 *tmp = NULL; 1169 *tmp = NULL;
1165 1170
1166 /* the device type may provide a specific name */ 1171 /* the device type may provide a specific name */
1167 if (dev->type && dev->type->nodename) 1172 if (dev->type && dev->type->devnode)
1168 *tmp = dev->type->nodename(dev); 1173 *tmp = dev->type->devnode(dev, mode);
1169 if (*tmp) 1174 if (*tmp)
1170 return *tmp; 1175 return *tmp;
1171 1176
1172 /* the class may provide a specific name */ 1177 /* the class may provide a specific name */
1173 if (dev->class && dev->class->nodename) 1178 if (dev->class && dev->class->devnode)
1174 *tmp = dev->class->nodename(dev); 1179 *tmp = dev->class->devnode(dev, mode);
1175 if (*tmp) 1180 if (*tmp)
1176 return *tmp; 1181 return *tmp;
1177 1182
diff --git a/drivers/base/devtmpfs.c b/drivers/base/devtmpfs.c
index fd488ad4263a..a1cb5afe6801 100644
--- a/drivers/base/devtmpfs.c
+++ b/drivers/base/devtmpfs.c
@@ -6,9 +6,10 @@
6 * During bootup, before any driver core device is registered, 6 * During bootup, before any driver core device is registered,
7 * devtmpfs, a tmpfs-based filesystem is created. Every driver-core 7 * devtmpfs, a tmpfs-based filesystem is created. Every driver-core
8 * device which requests a device node, will add a node in this 8 * device which requests a device node, will add a node in this
9 * filesystem. The node is named after the the name of the device, 9 * filesystem.
10 * or the susbsytem can provide a custom name. All devices are 10 * By default, all devices are named after the the name of the
11 * owned by root and have a mode of 0600. 11 * device, owned by root and have a default mode of 0600. Subsystems
12 * can overwrite the default setting if needed.
12 */ 13 */
13 14
14#include <linux/kernel.h> 15#include <linux/kernel.h>
@@ -20,6 +21,7 @@
20#include <linux/fs.h> 21#include <linux/fs.h>
21#include <linux/shmem_fs.h> 22#include <linux/shmem_fs.h>
22#include <linux/cred.h> 23#include <linux/cred.h>
24#include <linux/sched.h>
23#include <linux/init_task.h> 25#include <linux/init_task.h>
24 26
25static struct vfsmount *dev_mnt; 27static struct vfsmount *dev_mnt;
@@ -134,7 +136,7 @@ int devtmpfs_create_node(struct device *dev)
134 const char *tmp = NULL; 136 const char *tmp = NULL;
135 const char *nodename; 137 const char *nodename;
136 const struct cred *curr_cred; 138 const struct cred *curr_cred;
137 mode_t mode; 139 mode_t mode = 0;
138 struct nameidata nd; 140 struct nameidata nd;
139 struct dentry *dentry; 141 struct dentry *dentry;
140 int err; 142 int err;
@@ -142,14 +144,16 @@ int devtmpfs_create_node(struct device *dev)
142 if (!dev_mnt) 144 if (!dev_mnt)
143 return 0; 145 return 0;
144 146
145 nodename = device_get_nodename(dev, &tmp); 147 nodename = device_get_devnode(dev, &mode, &tmp);
146 if (!nodename) 148 if (!nodename)
147 return -ENOMEM; 149 return -ENOMEM;
148 150
151 if (mode == 0)
152 mode = 0600;
149 if (is_blockdev(dev)) 153 if (is_blockdev(dev))
150 mode = S_IFBLK|0600; 154 mode |= S_IFBLK;
151 else 155 else
152 mode = S_IFCHR|0600; 156 mode |= S_IFCHR;
153 157
154 curr_cred = override_creds(&init_cred); 158 curr_cred = override_creds(&init_cred);
155 err = vfs_path_lookup(dev_mnt->mnt_root, dev_mnt, 159 err = vfs_path_lookup(dev_mnt->mnt_root, dev_mnt,
@@ -165,8 +169,12 @@ int devtmpfs_create_node(struct device *dev)
165 169
166 dentry = lookup_create(&nd, 0); 170 dentry = lookup_create(&nd, 0);
167 if (!IS_ERR(dentry)) { 171 if (!IS_ERR(dentry)) {
172 int umask;
173
174 umask = sys_umask(0000);
168 err = vfs_mknod(nd.path.dentry->d_inode, 175 err = vfs_mknod(nd.path.dentry->d_inode,
169 dentry, mode, dev->devt); 176 dentry, mode, dev->devt);
177 sys_umask(umask);
170 /* mark as kernel created inode */ 178 /* mark as kernel created inode */
171 if (!err) 179 if (!err)
172 dentry->d_inode->i_private = &dev_mnt; 180 dentry->d_inode->i_private = &dev_mnt;
@@ -271,7 +279,7 @@ int devtmpfs_delete_node(struct device *dev)
271 if (!dev_mnt) 279 if (!dev_mnt)
272 return 0; 280 return 0;
273 281
274 nodename = device_get_nodename(dev, &tmp); 282 nodename = device_get_devnode(dev, NULL, &tmp);
275 if (!nodename) 283 if (!nodename)
276 return -ENOMEM; 284 return -ENOMEM;
277 285