[PATCH] sanitize hppfs

* hppfs_iget() and its users are racy; there's no need to pollute icache
anyway, new_inode() works fine and is safe, unlike the current kludges
(these relied on overwriting ->i_ino before another iget_locked() gets
to that one - and did it after unlocking).
* merge hppfs_iget()/init_inode()/hppfs_read_inode(), while we are
at it.
* to pass proper vfsmount to dentry_open() store the reference
in hppfs superblock.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
--

Al Viro f382d6e6 1dd0dd11

+34 -79
+34 -79
fs/hppfs/hppfs_kern.c
··· 18 #include <asm/uaccess.h> 19 #include "os.h" 20 21 - static int init_inode(struct inode *inode, struct dentry *dentry, 22 - struct vfsmount *mnt); 23 24 struct hppfs_data { 25 struct list_head list; ··· 34 35 struct hppfs_inode_info { 36 struct dentry *proc_dentry; 37 - struct vfsmount *proc_mnt; 38 struct inode vfs_inode; 39 }; 40 ··· 135 return 0; 136 } 137 138 - static void hppfs_read_inode(struct inode *ino) 139 - { 140 - struct inode *proc_ino; 141 - 142 - if (HPPFS_I(ino)->proc_dentry == NULL) 143 - return; 144 - 145 - proc_ino = HPPFS_I(ino)->proc_dentry->d_inode; 146 - ino->i_uid = proc_ino->i_uid; 147 - ino->i_gid = proc_ino->i_gid; 148 - ino->i_atime = proc_ino->i_atime; 149 - ino->i_mtime = proc_ino->i_mtime; 150 - ino->i_ctime = proc_ino->i_ctime; 151 - ino->i_ino = proc_ino->i_ino; 152 - ino->i_mode = proc_ino->i_mode; 153 - ino->i_nlink = proc_ino->i_nlink; 154 - ino->i_size = proc_ino->i_size; 155 - ino->i_blocks = proc_ino->i_blocks; 156 - } 157 - 158 - static struct inode *hppfs_iget(struct super_block *sb) 159 - { 160 - struct inode *inode; 161 - 162 - inode = iget_locked(sb, 0); 163 - if (!inode) 164 - return ERR_PTR(-ENOMEM); 165 - if (inode->i_state & I_NEW) { 166 - hppfs_read_inode(inode); 167 - unlock_new_inode(inode); 168 - } 169 - return inode; 170 - } 171 - 172 static struct dentry *hppfs_lookup(struct inode *ino, struct dentry *dentry, 173 struct nameidata *nd) 174 { ··· 170 if (IS_ERR(proc_dentry)) 171 return proc_dentry; 172 173 - inode = hppfs_iget(ino->i_sb); 174 - if (IS_ERR(inode)) { 175 - err = PTR_ERR(inode); 176 goto out_dput; 177 - } 178 - 179 - err = init_inode(inode, proc_dentry, HPPFS_I(ino)->proc_mnt); 180 - if (err) 181 - goto out_put; 182 - 183 - hppfs_read_inode(inode); 184 185 d_add(dentry, inode); 186 return NULL; 187 188 - out_put: 189 - iput(inode); 190 out_dput: 191 dput(proc_dentry); 192 out: ··· 444 goto out_free2; 445 446 proc_dentry = HPPFS_I(inode)->proc_dentry; 447 - proc_mnt = HPPFS_I(inode)->proc_mnt; 448 449 /* XXX This isn't closed anywhere */ 450 data->proc_file = dentry_open(dget(proc_dentry), mntget(proc_mnt), ··· 502 goto out; 503 504 proc_dentry = HPPFS_I(inode)->proc_dentry; 505 - proc_mnt = HPPFS_I(inode)->proc_mnt; 506 data->proc_file = dentry_open(dget(proc_dentry), mntget(proc_mnt), 507 file_mode(file->f_mode)); 508 err = PTR_ERR(data->proc_file); ··· 614 return NULL; 615 616 hi->proc_dentry = NULL; 617 - hi->proc_mnt = NULL; 618 inode_init_once(&hi->vfs_inode); 619 return &hi->vfs_inode; 620 } ··· 630 631 static void hppfs_put_super(struct super_block *sb) 632 { 633 - mntput(HPPFS_I(sb->s_root->d_inode)->proc_mnt); 634 } 635 636 static const struct super_operations hppfs_sbops = { ··· 650 int ret; 651 652 proc_dentry = HPPFS_I(dentry->d_inode)->proc_dentry; 653 - proc_mnt = HPPFS_I(dentry->d_inode)->proc_mnt; 654 655 proc_file = dentry_open(dget(proc_dentry), mntget(proc_mnt), O_RDONLY); 656 if (IS_ERR(proc_file)) ··· 671 void *ret; 672 673 proc_dentry = HPPFS_I(dentry->d_inode)->proc_dentry; 674 - proc_mnt = HPPFS_I(dentry->d_inode)->proc_mnt; 675 676 proc_file = dentry_open(dget(proc_dentry), mntget(proc_mnt), O_RDONLY); 677 if (IS_ERR(proc_file)) ··· 693 .follow_link = hppfs_follow_link, 694 }; 695 696 - static int init_inode(struct inode *inode, struct dentry *dentry, 697 - struct vfsmount *mnt) 698 { 699 if (S_ISDIR(dentry->d_inode->i_mode)) { 700 inode->i_op = &hppfs_dir_iops; 701 inode->i_fop = &hppfs_dir_fops; ··· 713 } 714 715 HPPFS_I(inode)->proc_dentry = dentry; 716 - HPPFS_I(inode)->proc_mnt = mnt; 717 718 return 0; 719 } ··· 731 static int hppfs_fill_super(struct super_block *sb, void *d, int silent) 732 { 733 struct inode *root_inode; 734 - struct file_system_type *procfs; 735 struct vfsmount *proc_mnt; 736 - int err; 737 738 - err = -ENOENT; 739 - procfs = get_fs_type("proc"); 740 - if (!procfs) 741 - goto out; 742 - 743 - proc_mnt = vfs_kern_mount(procfs, 0, procfs->name, NULL); 744 - put_filesystem(procfs); 745 if (IS_ERR(proc_mnt)) 746 goto out; 747 ··· 742 sb->s_blocksize_bits = 10; 743 sb->s_magic = HPPFS_SUPER_MAGIC; 744 sb->s_op = &hppfs_sbops; 745 - 746 - root_inode = hppfs_iget(sb); 747 - if (IS_ERR(root_inode)) { 748 - err = PTR_ERR(root_inode); 749 - goto out; 750 - } 751 - 752 - err = init_inode(root_inode, proc_mnt->mnt_sb->s_root, proc_mnt); 753 - if (err) 754 - goto out_iput; 755 756 err = -ENOMEM; 757 sb->s_root = d_alloc_root(root_inode); 758 if (!sb->s_root) 759 goto out_iput; 760 - 761 - hppfs_read_inode(root_inode); 762 763 return 0; 764
··· 18 #include <asm/uaccess.h> 19 #include "os.h" 20 21 + static struct inode *get_inode(struct super_block *, struct dentry *); 22 23 struct hppfs_data { 24 struct list_head list; ··· 35 36 struct hppfs_inode_info { 37 struct dentry *proc_dentry; 38 struct inode vfs_inode; 39 }; 40 ··· 137 return 0; 138 } 139 140 static struct dentry *hppfs_lookup(struct inode *ino, struct dentry *dentry, 141 struct nameidata *nd) 142 { ··· 206 if (IS_ERR(proc_dentry)) 207 return proc_dentry; 208 209 + err = -ENOMEM; 210 + inode = get_inode(ino->i_sb, proc_dentry); 211 + if (!inode) 212 goto out_dput; 213 214 d_add(dentry, inode); 215 return NULL; 216 217 out_dput: 218 dput(proc_dentry); 219 out: ··· 489 goto out_free2; 490 491 proc_dentry = HPPFS_I(inode)->proc_dentry; 492 + proc_mnt = inode->i_sb->s_fs_info; 493 494 /* XXX This isn't closed anywhere */ 495 data->proc_file = dentry_open(dget(proc_dentry), mntget(proc_mnt), ··· 547 goto out; 548 549 proc_dentry = HPPFS_I(inode)->proc_dentry; 550 + proc_mnt = inode->i_sb->s_fs_info; 551 data->proc_file = dentry_open(dget(proc_dentry), mntget(proc_mnt), 552 file_mode(file->f_mode)); 553 err = PTR_ERR(data->proc_file); ··· 659 return NULL; 660 661 hi->proc_dentry = NULL; 662 inode_init_once(&hi->vfs_inode); 663 return &hi->vfs_inode; 664 } ··· 676 677 static void hppfs_put_super(struct super_block *sb) 678 { 679 + mntput(sb->s_fs_info); 680 } 681 682 static const struct super_operations hppfs_sbops = { ··· 696 int ret; 697 698 proc_dentry = HPPFS_I(dentry->d_inode)->proc_dentry; 699 + proc_mnt = dentry->d_sb->s_fs_info; 700 701 proc_file = dentry_open(dget(proc_dentry), mntget(proc_mnt), O_RDONLY); 702 if (IS_ERR(proc_file)) ··· 717 void *ret; 718 719 proc_dentry = HPPFS_I(dentry->d_inode)->proc_dentry; 720 + proc_mnt = dentry->d_sb->s_fs_info; 721 722 proc_file = dentry_open(dget(proc_dentry), mntget(proc_mnt), O_RDONLY); 723 if (IS_ERR(proc_file)) ··· 739 .follow_link = hppfs_follow_link, 740 }; 741 742 + static struct inode *get_inode(struct super_block *sb, struct dentry *dentry) 743 { 744 + struct inode *proc_ino = dentry->d_inode; 745 + struct inode *inode = new_inode(sb); 746 + 747 + if (!inode) 748 + return ERR_PTR(-ENOMEM); 749 + 750 if (S_ISDIR(dentry->d_inode->i_mode)) { 751 inode->i_op = &hppfs_dir_iops; 752 inode->i_fop = &hppfs_dir_fops; ··· 754 } 755 756 HPPFS_I(inode)->proc_dentry = dentry; 757 + 758 + inode->i_uid = proc_ino->i_uid; 759 + inode->i_gid = proc_ino->i_gid; 760 + inode->i_atime = proc_ino->i_atime; 761 + inode->i_mtime = proc_ino->i_mtime; 762 + inode->i_ctime = proc_ino->i_ctime; 763 + inode->i_ino = proc_ino->i_ino; 764 + inode->i_mode = proc_ino->i_mode; 765 + inode->i_nlink = proc_ino->i_nlink; 766 + inode->i_size = proc_ino->i_size; 767 + inode->i_blocks = proc_ino->i_blocks; 768 769 return 0; 770 } ··· 762 static int hppfs_fill_super(struct super_block *sb, void *d, int silent) 763 { 764 struct inode *root_inode; 765 struct vfsmount *proc_mnt; 766 + int err = -ENOENT; 767 768 + proc_mnt = do_kern_mount("proc", 0, "proc", NULL); 769 if (IS_ERR(proc_mnt)) 770 goto out; 771 ··· 780 sb->s_blocksize_bits = 10; 781 sb->s_magic = HPPFS_SUPER_MAGIC; 782 sb->s_op = &hppfs_sbops; 783 + sb->s_fs_info = proc_mnt; 784 785 err = -ENOMEM; 786 + root_inode = get_inode(sb, proc_mnt->mnt_sb->s_root); 787 + if (!root_inode) 788 + goto out_mntput; 789 + 790 sb->s_root = d_alloc_root(root_inode); 791 if (!sb->s_root) 792 goto out_iput; 793 794 return 0; 795