Commit b6cdc731 authored by Al Viro's avatar Al Viro

procfs: don't allow to use proc_create, create_proc_entry, etc. for directories

Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent 21ba37c9
...@@ -541,19 +541,18 @@ static int proc_register(struct proc_dir_entry * dir, struct proc_dir_entry * dp ...@@ -541,19 +541,18 @@ static int proc_register(struct proc_dir_entry * dir, struct proc_dir_entry * dp
return ret; return ret;
if (S_ISDIR(dp->mode)) { if (S_ISDIR(dp->mode)) {
if (dp->proc_iops == NULL) { dp->proc_fops = &proc_dir_operations;
dp->proc_fops = &proc_dir_operations; dp->proc_iops = &proc_dir_inode_operations;
dp->proc_iops = &proc_dir_inode_operations;
}
dir->nlink++; dir->nlink++;
} else if (S_ISLNK(dp->mode)) { } else if (S_ISLNK(dp->mode)) {
if (dp->proc_iops == NULL) dp->proc_iops = &proc_link_inode_operations;
dp->proc_iops = &proc_link_inode_operations;
} else if (S_ISREG(dp->mode)) { } else if (S_ISREG(dp->mode)) {
if (dp->proc_fops == NULL) if (dp->proc_fops == NULL)
dp->proc_fops = &proc_file_operations; dp->proc_fops = &proc_file_operations;
if (dp->proc_iops == NULL) dp->proc_iops = &proc_file_inode_operations;
dp->proc_iops = &proc_file_inode_operations; } else {
WARN_ON(1);
return -EINVAL;
} }
spin_lock(&proc_subdir_lock); spin_lock(&proc_subdir_lock);
...@@ -680,21 +679,19 @@ struct proc_dir_entry *create_proc_entry(const char *name, umode_t mode, ...@@ -680,21 +679,19 @@ struct proc_dir_entry *create_proc_entry(const char *name, umode_t mode,
struct proc_dir_entry *parent) struct proc_dir_entry *parent)
{ {
struct proc_dir_entry *ent; struct proc_dir_entry *ent;
nlink_t nlink;
if (S_ISDIR(mode)) { if ((mode & S_IFMT) == 0)
if ((mode & S_IALLUGO) == 0) mode |= S_IFREG;
mode |= S_IRUGO | S_IXUGO;
nlink = 2; if (!S_ISREG(mode)) {
} else { WARN_ON(1); /* use proc_mkdir(), damnit */
if ((mode & S_IFMT) == 0) return NULL;
mode |= S_IFREG;
if ((mode & S_IALLUGO) == 0)
mode |= S_IRUGO;
nlink = 1;
} }
ent = __proc_create(&parent, name, mode, nlink); if ((mode & S_IALLUGO) == 0)
mode |= S_IRUGO;
ent = __proc_create(&parent, name, mode, 1);
if (ent) { if (ent) {
if (proc_register(parent, ent) < 0) { if (proc_register(parent, ent) < 0) {
kfree(ent); kfree(ent);
...@@ -711,21 +708,17 @@ struct proc_dir_entry *proc_create_data(const char *name, umode_t mode, ...@@ -711,21 +708,17 @@ struct proc_dir_entry *proc_create_data(const char *name, umode_t mode,
void *data) void *data)
{ {
struct proc_dir_entry *pde; struct proc_dir_entry *pde;
nlink_t nlink; if ((mode & S_IFMT) == 0)
mode |= S_IFREG;
if (S_ISDIR(mode)) { if (!S_ISREG(mode)) {
if ((mode & S_IALLUGO) == 0) WARN_ON(1); /* use proc_mkdir() */
mode |= S_IRUGO | S_IXUGO; return NULL;
nlink = 2;
} else {
if ((mode & S_IFMT) == 0)
mode |= S_IFREG;
if ((mode & S_IALLUGO) == 0)
mode |= S_IRUGO;
nlink = 1;
} }
pde = __proc_create(&parent, name, mode, nlink); if ((mode & S_IALLUGO) == 0)
mode |= S_IRUGO;
pde = __proc_create(&parent, name, mode, 1);
if (!pde) if (!pde)
goto out; goto out;
pde->proc_fops = proc_fops; pde->proc_fops = proc_fops;
......
...@@ -462,8 +462,8 @@ struct inode *proc_get_inode(struct super_block *sb, struct proc_dir_entry *de) ...@@ -462,8 +462,8 @@ struct inode *proc_get_inode(struct super_block *sb, struct proc_dir_entry *de)
inode->i_size = de->size; inode->i_size = de->size;
if (de->nlink) if (de->nlink)
set_nlink(inode, de->nlink); set_nlink(inode, de->nlink);
if (de->proc_iops) WARN_ON(!de->proc_iops);
inode->i_op = de->proc_iops; inode->i_op = de->proc_iops;
if (de->proc_fops) { if (de->proc_fops) {
if (S_ISREG(inode->i_mode)) { if (S_ISREG(inode->i_mode)) {
#ifdef CONFIG_COMPAT #ifdef CONFIG_COMPAT
......
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