Commit 439c6109 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'driver-core-3.15-rc6' of...

Merge tag 'driver-core-3.15-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core

Pull driver core fixes from Greg KH:
 "Here are two driver core (well, sysfs) fixes for 3.15-rc6 that resolve
  some reported issues and a regression from 3.13"

* tag 'driver-core-3.15-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core:
  sysfs: make sure read buffer is zeroed
  kernfs, sysfs, cgroup: restrict extra perm check on open to sysfs
parents 957cf258 f5c16f29
...@@ -610,6 +610,7 @@ static void kernfs_put_open_node(struct kernfs_node *kn, ...@@ -610,6 +610,7 @@ static void kernfs_put_open_node(struct kernfs_node *kn,
static int kernfs_fop_open(struct inode *inode, struct file *file) static int kernfs_fop_open(struct inode *inode, struct file *file)
{ {
struct kernfs_node *kn = file->f_path.dentry->d_fsdata; struct kernfs_node *kn = file->f_path.dentry->d_fsdata;
struct kernfs_root *root = kernfs_root(kn);
const struct kernfs_ops *ops; const struct kernfs_ops *ops;
struct kernfs_open_file *of; struct kernfs_open_file *of;
bool has_read, has_write, has_mmap; bool has_read, has_write, has_mmap;
...@@ -624,7 +625,8 @@ static int kernfs_fop_open(struct inode *inode, struct file *file) ...@@ -624,7 +625,8 @@ static int kernfs_fop_open(struct inode *inode, struct file *file)
has_write = ops->write || ops->mmap; has_write = ops->write || ops->mmap;
has_mmap = ops->mmap; has_mmap = ops->mmap;
/* check perms and supported operations */ /* see the flag definition for details */
if (root->flags & KERNFS_ROOT_EXTRA_OPEN_PERM_CHECK) {
if ((file->f_mode & FMODE_WRITE) && if ((file->f_mode & FMODE_WRITE) &&
(!(inode->i_mode & S_IWUGO) || !has_write)) (!(inode->i_mode & S_IWUGO) || !has_write))
goto err_out; goto err_out;
...@@ -632,6 +634,7 @@ static int kernfs_fop_open(struct inode *inode, struct file *file) ...@@ -632,6 +634,7 @@ static int kernfs_fop_open(struct inode *inode, struct file *file)
if ((file->f_mode & FMODE_READ) && if ((file->f_mode & FMODE_READ) &&
(!(inode->i_mode & S_IRUGO) || !has_read)) (!(inode->i_mode & S_IRUGO) || !has_read))
goto err_out; goto err_out;
}
/* allocate a kernfs_open_file for the file */ /* allocate a kernfs_open_file for the file */
error = -ENOMEM; error = -ENOMEM;
......
...@@ -47,12 +47,13 @@ static int sysfs_kf_seq_show(struct seq_file *sf, void *v) ...@@ -47,12 +47,13 @@ static int sysfs_kf_seq_show(struct seq_file *sf, void *v)
ssize_t count; ssize_t count;
char *buf; char *buf;
/* acquire buffer and ensure that it's >= PAGE_SIZE */ /* acquire buffer and ensure that it's >= PAGE_SIZE and clear */
count = seq_get_buf(sf, &buf); count = seq_get_buf(sf, &buf);
if (count < PAGE_SIZE) { if (count < PAGE_SIZE) {
seq_commit(sf, -1); seq_commit(sf, -1);
return 0; return 0;
} }
memset(buf, 0, PAGE_SIZE);
/* /*
* Invoke show(). Control may reach here via seq file lseek even * Invoke show(). Control may reach here via seq file lseek even
......
...@@ -63,7 +63,8 @@ int __init sysfs_init(void) ...@@ -63,7 +63,8 @@ int __init sysfs_init(void)
{ {
int err; int err;
sysfs_root = kernfs_create_root(NULL, 0, NULL); sysfs_root = kernfs_create_root(NULL, KERNFS_ROOT_EXTRA_OPEN_PERM_CHECK,
NULL);
if (IS_ERR(sysfs_root)) if (IS_ERR(sysfs_root))
return PTR_ERR(sysfs_root); return PTR_ERR(sysfs_root);
......
...@@ -50,7 +50,24 @@ enum kernfs_node_flag { ...@@ -50,7 +50,24 @@ enum kernfs_node_flag {
/* @flags for kernfs_create_root() */ /* @flags for kernfs_create_root() */
enum kernfs_root_flag { enum kernfs_root_flag {
/*
* kernfs_nodes are created in the deactivated state and invisible.
* They require explicit kernfs_activate() to become visible. This
* can be used to make related nodes become visible atomically
* after all nodes are created successfully.
*/
KERNFS_ROOT_CREATE_DEACTIVATED = 0x0001, KERNFS_ROOT_CREATE_DEACTIVATED = 0x0001,
/*
* For regular flies, if the opener has CAP_DAC_OVERRIDE, open(2)
* succeeds regardless of the RW permissions. sysfs had an extra
* layer of enforcement where open(2) fails with -EACCES regardless
* of CAP_DAC_OVERRIDE if the permission doesn't have the
* respective read or write access at all (none of S_IRUGO or
* S_IWUGO) or the respective operation isn't implemented. The
* following flag enables that behavior.
*/
KERNFS_ROOT_EXTRA_OPEN_PERM_CHECK = 0x0002,
}; };
/* type-specific structures for kernfs_node union members */ /* type-specific structures for kernfs_node union members */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment