aboutsummaryrefslogtreecommitdiffstats
path: root/fs/proc
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2013-03-30 21:20:14 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2013-04-09 14:13:14 -0400
commitb6cdc7310338e204224f865918f774eb6db0b75d (patch)
tree0525092aeb3cc02dbe67b41444444cfc7cd4449a /fs/proc
parent21ba37c9cf2f2dcadaabd79dff384537124d216c (diff)
procfs: don't allow to use proc_create, create_proc_entry, etc. for directories
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/proc')
-rw-r--r--fs/proc/generic.c57
-rw-r--r--fs/proc/inode.c4
2 files changed, 27 insertions, 34 deletions
diff --git a/fs/proc/generic.c b/fs/proc/generic.c
index 21e1a8f1659d..6bce60703c76 100644
--- a/fs/proc/generic.c
+++ b/fs/proc/generic.c
@@ -541,19 +541,18 @@ static int proc_register(struct proc_dir_entry * dir, struct proc_dir_entry * dp
541 return ret; 541 return ret;
542 542
543 if (S_ISDIR(dp->mode)) { 543 if (S_ISDIR(dp->mode)) {
544 if (dp->proc_iops == NULL) { 544 dp->proc_fops = &proc_dir_operations;
545 dp->proc_fops = &proc_dir_operations; 545 dp->proc_iops = &proc_dir_inode_operations;
546 dp->proc_iops = &proc_dir_inode_operations;
547 }
548 dir->nlink++; 546 dir->nlink++;
549 } else if (S_ISLNK(dp->mode)) { 547 } else if (S_ISLNK(dp->mode)) {
550 if (dp->proc_iops == NULL) 548 dp->proc_iops = &proc_link_inode_operations;
551 dp->proc_iops = &proc_link_inode_operations;
552 } else if (S_ISREG(dp->mode)) { 549 } else if (S_ISREG(dp->mode)) {
553 if (dp->proc_fops == NULL) 550 if (dp->proc_fops == NULL)
554 dp->proc_fops = &proc_file_operations; 551 dp->proc_fops = &proc_file_operations;
555 if (dp->proc_iops == NULL) 552 dp->proc_iops = &proc_file_inode_operations;
556 dp->proc_iops = &proc_file_inode_operations; 553 } else {
554 WARN_ON(1);
555 return -EINVAL;
557 } 556 }
558 557
559 spin_lock(&proc_subdir_lock); 558 spin_lock(&proc_subdir_lock);
@@ -680,21 +679,19 @@ struct proc_dir_entry *create_proc_entry(const char *name, umode_t mode,
680 struct proc_dir_entry *parent) 679 struct proc_dir_entry *parent)
681{ 680{
682 struct proc_dir_entry *ent; 681 struct proc_dir_entry *ent;
683 nlink_t nlink;
684 682
685 if (S_ISDIR(mode)) { 683 if ((mode & S_IFMT) == 0)
686 if ((mode & S_IALLUGO) == 0) 684 mode |= S_IFREG;
687 mode |= S_IRUGO | S_IXUGO; 685
688 nlink = 2; 686 if (!S_ISREG(mode)) {
689 } else { 687 WARN_ON(1); /* use proc_mkdir(), damnit */
690 if ((mode & S_IFMT) == 0) 688 return NULL;
691 mode |= S_IFREG;
692 if ((mode & S_IALLUGO) == 0)
693 mode |= S_IRUGO;
694 nlink = 1;
695 } 689 }
696 690
697 ent = __proc_create(&parent, name, mode, nlink); 691 if ((mode & S_IALLUGO) == 0)
692 mode |= S_IRUGO;
693
694 ent = __proc_create(&parent, name, mode, 1);
698 if (ent) { 695 if (ent) {
699 if (proc_register(parent, ent) < 0) { 696 if (proc_register(parent, ent) < 0) {
700 kfree(ent); 697 kfree(ent);
@@ -711,21 +708,17 @@ struct proc_dir_entry *proc_create_data(const char *name, umode_t mode,
711 void *data) 708 void *data)
712{ 709{
713 struct proc_dir_entry *pde; 710 struct proc_dir_entry *pde;
714 nlink_t nlink; 711 if ((mode & S_IFMT) == 0)
712 mode |= S_IFREG;
715 713
716 if (S_ISDIR(mode)) { 714 if (!S_ISREG(mode)) {
717 if ((mode & S_IALLUGO) == 0) 715 WARN_ON(1); /* use proc_mkdir() */
718 mode |= S_IRUGO | S_IXUGO; 716 return NULL;
719 nlink = 2;
720 } else {
721 if ((mode & S_IFMT) == 0)
722 mode |= S_IFREG;
723 if ((mode & S_IALLUGO) == 0)
724 mode |= S_IRUGO;
725 nlink = 1;
726 } 717 }
727 718
728 pde = __proc_create(&parent, name, mode, nlink); 719 if ((mode & S_IALLUGO) == 0)
720 mode |= S_IRUGO;
721 pde = __proc_create(&parent, name, mode, 1);
729 if (!pde) 722 if (!pde)
730 goto out; 723 goto out;
731 pde->proc_fops = proc_fops; 724 pde->proc_fops = proc_fops;
diff --git a/fs/proc/inode.c b/fs/proc/inode.c
index 908e97457319..a4aaaeee3342 100644
--- a/fs/proc/inode.c
+++ b/fs/proc/inode.c
@@ -462,8 +462,8 @@ struct inode *proc_get_inode(struct super_block *sb, struct proc_dir_entry *de)
462 inode->i_size = de->size; 462 inode->i_size = de->size;
463 if (de->nlink) 463 if (de->nlink)
464 set_nlink(inode, de->nlink); 464 set_nlink(inode, de->nlink);
465 if (de->proc_iops) 465 WARN_ON(!de->proc_iops);
466 inode->i_op = de->proc_iops; 466 inode->i_op = de->proc_iops;
467 if (de->proc_fops) { 467 if (de->proc_fops) {
468 if (S_ISREG(inode->i_mode)) { 468 if (S_ISREG(inode->i_mode)) {
469#ifdef CONFIG_COMPAT 469#ifdef CONFIG_COMPAT