diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2013-03-30 21:20:14 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2013-04-09 14:13:14 -0400 |
commit | b6cdc7310338e204224f865918f774eb6db0b75d (patch) | |
tree | 0525092aeb3cc02dbe67b41444444cfc7cd4449a /fs/proc | |
parent | 21ba37c9cf2f2dcadaabd79dff384537124d216c (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.c | 57 | ||||
-rw-r--r-- | fs/proc/inode.c | 4 |
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 |