Subject: [PATCH] Add a mnt paramenter to follow_link From: Eric W. Biederman Date: 1129564951 -0600 This allows magic follow_link methods to work properly in the presence of mount points. This also updates /proc/root.c to use the new capabilities. --- fs/9p/vfs_inode.c | 2 +- fs/afs/mntpt.c | 4 ++-- fs/autofs/symlink.c | 2 +- fs/autofs4/symlink.c | 2 +- fs/befs/linuxvfs.c | 4 ++-- fs/cifs/cifsfs.h | 2 +- fs/cifs/link.c | 2 +- fs/devfs/base.c | 2 +- fs/ext2/symlink.c | 2 +- fs/ext3/symlink.c | 2 +- fs/freevxfs/vxfs_immed.c | 4 ++-- fs/fuse/dir.c | 2 +- fs/hppfs/hppfs_kern.c | 2 +- fs/jffs2/symlink.c | 4 ++-- fs/jfs/symlink.c | 2 +- fs/namei.c | 10 +++++----- fs/nfs/symlink.c | 2 +- fs/proc/base.c | 4 ++-- fs/proc/generic.c | 2 +- fs/proc/inode.c | 4 ++++ fs/proc/internal.h | 1 - fs/proc/root.c | 42 ++++++++++++++++++++++++++++++++++++++++-- fs/smbfs/symlink.c | 2 +- fs/sysfs/symlink.c | 2 +- fs/sysv/symlink.c | 2 +- fs/ufs/symlink.c | 2 +- fs/xfs/linux-2.6/xfs_iops.c | 1 + include/linux/fs.h | 4 ++-- include/linux/pspace.h | 4 ++++ include/linux/security.h | 9 +++++---- kernel/pid.c | 2 ++ mm/shmem.c | 4 ++-- security/dummy.c | 2 +- security/selinux/hooks.c | 4 ++-- 34 files changed, 95 insertions(+), 46 deletions(-) c72bcd2e9a299ed5ea52dedbb4d0051ca91896da diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c index 2b696ae..2f5d029 100644 --- a/fs/9p/vfs_inode.c +++ b/fs/9p/vfs_inode.c @@ -1116,7 +1116,7 @@ static int v9fs_vfs_readlink(struct dent * */ -static void *v9fs_vfs_follow_link(struct dentry *dentry, struct nameidata *nd) +static void *v9fs_vfs_follow_link(struct vfsmount *mnt, struct dentry *dentry, struct nameidata *nd) { int len = 0; char *link = __getname(); diff --git a/fs/afs/mntpt.c b/fs/afs/mntpt.c index 31ee065..faf29de 100644 --- a/fs/afs/mntpt.c +++ b/fs/afs/mntpt.c @@ -30,7 +30,7 @@ static struct dentry *afs_mntpt_lookup(s struct dentry *dentry, struct nameidata *nd); static int afs_mntpt_open(struct inode *inode, struct file *file); -static void *afs_mntpt_follow_link(struct dentry *dentry, struct nameidata *nd); +static void *afs_mntpt_follow_link(struct vfsmount *mnt, struct dentry *dentry, struct nameidata *nd); struct file_operations afs_mntpt_file_operations = { .open = afs_mntpt_open, @@ -233,7 +233,7 @@ static struct vfsmount *afs_mntpt_do_aut /* * follow a link from a mountpoint directory, thus causing it to be mounted */ -static void *afs_mntpt_follow_link(struct dentry *dentry, struct nameidata *nd) +static void *afs_mntpt_follow_link(struct vfsmount *mnt, struct dentry *dentry, struct nameidata *nd) { struct vfsmount *newmnt; struct dentry *old_dentry; diff --git a/fs/autofs/symlink.c b/fs/autofs/symlink.c index 52e8772..9567bf2 100644 --- a/fs/autofs/symlink.c +++ b/fs/autofs/symlink.c @@ -13,7 +13,7 @@ #include "autofs_i.h" /* Nothing to release.. */ -static void *autofs_follow_link(struct dentry *dentry, struct nameidata *nd) +static void *autofs_follow_link(struct vfsmount *mnt, struct dentry *dentry, struct nameidata *nd) { char *s=((struct autofs_symlink *)dentry->d_inode->u.generic_ip)->data; nd_set_link(nd, s); diff --git a/fs/autofs4/symlink.c b/fs/autofs4/symlink.c index 2ea2c98..9e7b7cb 100644 --- a/fs/autofs4/symlink.c +++ b/fs/autofs4/symlink.c @@ -12,7 +12,7 @@ #include "autofs_i.h" -static void *autofs4_follow_link(struct dentry *dentry, struct nameidata *nd) +static void *autofs4_follow_link(struct vfsmount *mnt, struct dentry *dentry, struct nameidata *nd) { struct autofs_info *ino = autofs4_dentry_ino(dentry); nd_set_link(nd, (char *)ino->u.symlink); diff --git a/fs/befs/linuxvfs.c b/fs/befs/linuxvfs.c index e0a6025..c58c061 100644 --- a/fs/befs/linuxvfs.c +++ b/fs/befs/linuxvfs.c @@ -41,7 +41,7 @@ static struct inode *befs_alloc_inode(st static void befs_destroy_inode(struct inode *inode); static int befs_init_inodecache(void); static void befs_destroy_inodecache(void); -static void *befs_follow_link(struct dentry *, struct nameidata *); +static void *befs_follow_link(struct vfsmount *, struct dentry *, struct nameidata *); static void befs_put_link(struct dentry *, struct nameidata *, void *); static int befs_utf2nls(struct super_block *sb, const char *in, int in_len, char **out, int *out_len); @@ -462,7 +462,7 @@ befs_destroy_inodecache(void) * flag is set. */ static void * -befs_follow_link(struct dentry *dentry, struct nameidata *nd) +befs_follow_link(struct vfsmount *, struct dentry *dentry, struct nameidata *nd) { befs_inode_info *befs_ino = BEFS_I(dentry->d_inode); char *link; diff --git a/fs/cifs/cifsfs.h b/fs/cifs/cifsfs.h index 1fd21f6..367e55a 100644 --- a/fs/cifs/cifsfs.h +++ b/fs/cifs/cifsfs.h @@ -83,7 +83,7 @@ extern int cifs_dir_notify(struct file * extern struct dentry_operations cifs_dentry_ops; /* Functions related to symlinks */ -extern void *cifs_follow_link(struct dentry *direntry, struct nameidata *nd); +extern void *cifs_follow_link(struct vfsmount *mnt, struct dentry *direntry, struct nameidata *nd); extern void cifs_put_link(struct dentry *direntry, struct nameidata *nd, void *); extern int cifs_readlink(struct dentry *direntry, char __user *buffer, int buflen); diff --git a/fs/cifs/link.c b/fs/cifs/link.c index ab925ef..a8a751a 100644 --- a/fs/cifs/link.c +++ b/fs/cifs/link.c @@ -93,7 +93,7 @@ cifs_hl_exit: } void * -cifs_follow_link(struct dentry *direntry, struct nameidata *nd) +cifs_follow_link(struct vfsmount *mnt, struct dentry *direntry, struct nameidata *nd) { struct inode *inode = direntry->d_inode; int rc = -EACCES; diff --git a/fs/devfs/base.c b/fs/devfs/base.c index 8b679b6..3574d56 100644 --- a/fs/devfs/base.c +++ b/fs/devfs/base.c @@ -2491,7 +2491,7 @@ static int devfs_mknod(struct inode *dir return 0; } /* End Function devfs_mknod */ -static void *devfs_follow_link(struct dentry *dentry, struct nameidata *nd) +static void *devfs_follow_link(struct vfslink *mnt, struct dentry *dentry, struct nameidata *nd) { struct devfs_entry *p = get_devfs_entry_from_vfs_inode(dentry->d_inode); nd_set_link(nd, p ? p->u.symlink.linkname : ERR_PTR(-ENODEV)); diff --git a/fs/ext2/symlink.c b/fs/ext2/symlink.c index 1e67d87..ec0d8f7 100644 --- a/fs/ext2/symlink.c +++ b/fs/ext2/symlink.c @@ -21,7 +21,7 @@ #include "xattr.h" #include -static void *ext2_follow_link(struct dentry *dentry, struct nameidata *nd) +static void *ext2_follow_link(struct vfsmount *mnt, struct dentry *dentry, struct nameidata *nd) { struct ext2_inode_info *ei = EXT2_I(dentry->d_inode); nd_set_link(nd, (char *)ei->i_data); diff --git a/fs/ext3/symlink.c b/fs/ext3/symlink.c index 4f79122..c74f278 100644 --- a/fs/ext3/symlink.c +++ b/fs/ext3/symlink.c @@ -23,7 +23,7 @@ #include #include "xattr.h" -static void * ext3_follow_link(struct dentry *dentry, struct nameidata *nd) +static void * ext3_follow_link(struct vfsmount *mnt, struct dentry *dentry, struct nameidata *nd) { struct ext3_inode_info *ei = EXT3_I(dentry->d_inode); nd_set_link(nd, (char*)ei->i_data); diff --git a/fs/freevxfs/vxfs_immed.c b/fs/freevxfs/vxfs_immed.c index d0401dc..1ee886c 100644 --- a/fs/freevxfs/vxfs_immed.c +++ b/fs/freevxfs/vxfs_immed.c @@ -38,7 +38,7 @@ #include "vxfs_inode.h" -static void * vxfs_immed_follow_link(struct dentry *, struct nameidata *); +static void * vxfs_immed_follow_link(struct vfsmount *, struct dentry *, struct nameidata *); static int vxfs_immed_readpage(struct file *, struct page *); @@ -73,7 +73,7 @@ struct address_space_operations vxfs_imm * Zero on success, else a negative error code. */ static void * -vxfs_immed_follow_link(struct dentry *dp, struct nameidata *np) +vxfs_immed_follow_link(struct vfsmount *mnt, struct dentry *dp, struct nameidata *np) { struct vxfs_inode_info *vip = VXFS_INO(dp->d_inode); nd_set_link(np, vip->vii_immed.vi_immed); diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c index 29f1e9f..cf68147 100644 --- a/fs/fuse/dir.c +++ b/fs/fuse/dir.c @@ -602,7 +602,7 @@ static void free_link(char *link) free_page((unsigned long) link); } -static void *fuse_follow_link(struct dentry *dentry, struct nameidata *nd) +static void *fuse_follow_link(struct vfsmount *mnt, struct dentry *dentry, struct nameidata *nd) { nd_set_link(nd, read_link(dentry)); return NULL; diff --git a/fs/hppfs/hppfs_kern.c b/fs/hppfs/hppfs_kern.c index 5293091..1c6337b 100644 --- a/fs/hppfs/hppfs_kern.c +++ b/fs/hppfs/hppfs_kern.c @@ -676,7 +676,7 @@ static int hppfs_readlink(struct dentry return ret; } -static void* hppfs_follow_link(struct dentry *dentry, struct nameidata *nd) +static void* hppfs_follow_link(struct vfsmount *mnt, struct dentry *dentry, struct nameidata *nd) { struct file *proc_file; struct dentry *proc_dentry; diff --git a/fs/jffs2/symlink.c b/fs/jffs2/symlink.c index 82ef484..90a4984 100644 --- a/fs/jffs2/symlink.c +++ b/fs/jffs2/symlink.c @@ -18,7 +18,7 @@ #include #include "nodelist.h" -static void *jffs2_follow_link(struct dentry *dentry, struct nameidata *nd); +static void *jffs2_follow_link(struct vfsmount *mnt, struct dentry *dentry, struct nameidata *nd); struct inode_operations jffs2_symlink_inode_operations = { @@ -27,7 +27,7 @@ struct inode_operations jffs2_symlink_in .setattr = jffs2_setattr }; -static void *jffs2_follow_link(struct dentry *dentry, struct nameidata *nd) +static void *jffs2_follow_link(struct vfsmount *mnt, struct dentry *dentry, struct nameidata *nd) { struct jffs2_inode_info *f = JFFS2_INODE_INFO(dentry->d_inode); char *p = (char *)f->dents; diff --git a/fs/jfs/symlink.c b/fs/jfs/symlink.c index 16477b3..8569aa8 100644 --- a/fs/jfs/symlink.c +++ b/fs/jfs/symlink.c @@ -22,7 +22,7 @@ #include "jfs_inode.h" #include "jfs_xattr.h" -static void *jfs_follow_link(struct dentry *dentry, struct nameidata *nd) +static void *jfs_follow_link(struct vfsmount *mnt, struct dentry *dentry, struct nameidata *nd) { char *s = JFS_IP(dentry->d_inode)->i_inline; nd_set_link(nd, s); diff --git a/fs/namei.c b/fs/namei.c index aa62dbd..0eaa016 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -509,7 +509,7 @@ static inline int __do_follow_link(struc if (path->mnt == nd->mnt) mntget(path->mnt); - cookie = dentry->d_inode->i_op->follow_link(dentry, nd); + cookie = dentry->d_inode->i_op->follow_link(path->mnt, dentry, nd); error = PTR_ERR(cookie); if (!IS_ERR(cookie)) { char *s = nd_get_link(nd); @@ -557,7 +557,7 @@ static inline int do_follow_link(struct goto loop; BUG_ON(nd->depth >= MAX_NESTED_LINKS); cond_resched(); - err = security_inode_follow_link(path->dentry, nd); + err = security_inode_follow_link(path->mnt, path->dentry, nd); if (err) goto loop; current->link_count++; @@ -1538,7 +1538,7 @@ do_link: * are done. Procfs-like symlinks just set LAST_BIND. */ nd->flags |= LOOKUP_PARENT; - error = security_inode_follow_link(path.dentry, nd); + error = security_inode_follow_link(path.mnt, path.dentry, nd); if (error) goto exit_dput; error = __do_follow_link(&path, nd); @@ -2332,7 +2332,7 @@ int generic_readlink(struct dentry *dent void *cookie; nd.depth = 0; - cookie = dentry->d_inode->i_op->follow_link(dentry, &nd); + cookie = dentry->d_inode->i_op->follow_link(NULL, dentry, &nd); if (!IS_ERR(cookie)) { int res = vfs_readlink(dentry, buffer, buflen, nd_get_link(&nd)); if (dentry->d_inode->i_op->put_link) @@ -2382,7 +2382,7 @@ int page_readlink(struct dentry *dentry, return res; } -void *page_follow_link_light(struct dentry *dentry, struct nameidata *nd) +void *page_follow_link_light(struct vfsmount *mnt, struct dentry *dentry, struct nameidata *nd) { struct page *page = NULL; nd_set_link(nd, page_getlink(dentry, &page)); diff --git a/fs/nfs/symlink.c b/fs/nfs/symlink.c index 18dc95b..d472627 100644 --- a/fs/nfs/symlink.c +++ b/fs/nfs/symlink.c @@ -48,7 +48,7 @@ error: return -EIO; } -static void *nfs_follow_link(struct dentry *dentry, struct nameidata *nd) +static void *nfs_follow_link(struct vfsmount *mnt, struct dentry *dentry, struct nameidata *nd) { struct inode *inode = dentry->d_inode; struct page *page; diff --git a/fs/proc/base.c b/fs/proc/base.c index 7d16b66..d4ccf34 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c @@ -1025,7 +1025,7 @@ static struct file_operations proc_secco }; #endif /* CONFIG_SECCOMP */ -static void *proc_pid_follow_link(struct dentry *dentry, struct nameidata *nd) +static void *proc_pid_follow_link(struct vfsmount *mnt, struct dentry *dentry, struct nameidata *nd) { struct inode *inode = dentry->d_inode; int error = -EACCES; @@ -1839,7 +1839,7 @@ static int proc_self_readlink(struct den return vfs_readlink(dentry,buffer,buflen,tmp); } -static void *proc_self_follow_link(struct dentry *dentry, struct nameidata *nd) +static void *proc_self_follow_link(struct vfsmount *mnt, struct dentry *dentry, struct nameidata *nd) { char tmp[30]; sprintf(tmp, "%d", pid_to_user(current->tgid)); diff --git a/fs/proc/generic.c b/fs/proc/generic.c index 8a8c344..90c6a45 100644 --- a/fs/proc/generic.c +++ b/fs/proc/generic.c @@ -341,7 +341,7 @@ static void release_inode_number(unsigne spin_unlock(&proc_inum_lock); } -static void *proc_follow_link(struct dentry *dentry, struct nameidata *nd) +static void *proc_follow_link(struct vfsmount *mnt, struct dentry *dentry, struct nameidata *nd) { nd_set_link(nd, PDE(dentry->d_inode)->data); return NULL; diff --git a/fs/proc/inode.c b/fs/proc/inode.c index 27b6df7..a55513b 100644 --- a/fs/proc/inode.c +++ b/fs/proc/inode.c @@ -188,6 +188,7 @@ out_fail: goto out; } +#if 0 static int do_proc_pspace_root_dentry(struct super_block *sb, struct pspace *pspace) { struct inode *root_inode; @@ -212,6 +213,7 @@ int proc_pspace_root_dentry(struct pspac { return do_proc_pspace_root_dentry(proc_sb(), pspace); } +#endif int proc_fill_super(struct super_block *s, void *data, int silent) { @@ -236,8 +238,10 @@ int proc_fill_super(struct super_block * if (!s->s_root) goto out_no_root; +#if 0 if (do_proc_pspace_root_dentry(s, &init_pspace)) goto out_no_root; +#endif return 0; out_no_root: diff --git a/fs/proc/internal.h b/fs/proc/internal.h index 1fca472..fb6df85 100644 --- a/fs/proc/internal.h +++ b/fs/proc/internal.h @@ -49,4 +49,3 @@ static inline int proc_type(struct inode } extern void free_proc_entry(struct proc_dir_entry *); -extern struct super_block *proc_sb(void); diff --git a/fs/proc/root.c b/fs/proc/root.c index 6102d6d..a20bd22 100644 --- a/fs/proc/root.c +++ b/fs/proc/root.c @@ -19,6 +19,7 @@ #include #include #include +#include #include "internal.h" struct proc_dir_entry *proc_net, *proc_net_stat, *proc_bus, *proc_root_fs, *proc_root_driver; @@ -39,10 +40,12 @@ static struct file_system_type proc_fs_t .kill_sb = kill_anon_super, }; +#if 0 struct super_block *proc_sb(void) { return get_sb_single(&proc_fs_type, 0, NULL, proc_fill_super); } +#endif extern int __init proc_init_inodecache(void); void __init proc_root_init(void) @@ -87,11 +90,44 @@ void __init proc_root_init(void) proc_bus = proc_mkdir("bus", NULL); } -static void *proc_root_follow_link(struct dentry *dentry, struct nameidata *nd) +static void *proc_root_follow_link(struct vfsmount *mnt, struct dentry *dentry, struct nameidata *nd) { /* Follow the pseudo link to the per pspace root of the /proc filesystem */ + struct inode *root = dentry->d_inode; + struct qstr str; + + /* Install the mount and drop the dentry */ + mntget(mnt); dput(nd->dentry); - nd->dentry = dget(current->pspace->proc_root); + mntput(nd->mnt); + nd->mnt = mnt; + + /* Use a name of length 0 so it is not visible to user space. + * This relies on all of the information needed to be mached + * being placed in str.hash. + * + * FIXME: We are safe with 32bit pointers there is a remote + * possibility of a hash collision with 64bit pointers. + */ + str.name = "\0"; + str.len = 0; + str.hash = ((unsigned long)(current->pspace))/sizeof(struct pspace); + + /* See if I already have the pspace dentry and if not create it */ + down(&root->i_sem); + nd->dentry = d_lookup(dentry, &str); + if (!nd->dentry) { + nd->dentry = d_alloc(dentry, &str); + if (nd->dentry) { + nd->dentry->d_fsdata = current->pspace; + d_add(nd->dentry, root); + __iget(root); + } else { + nd->dentry = ERR_PTR(-ENOMEM); + } + } + up(&root->i_sem); + return NULL; } @@ -149,7 +185,9 @@ static struct file_operations proc_root_ */ static struct inode_operations proc_root_inode_operations = { .lookup = proc_root_lookup, +#if 1 .follow_link = proc_root_follow_link, +#endif }; /* diff --git a/fs/smbfs/symlink.c b/fs/smbfs/symlink.c index 0c64bc3..c41274d 100644 --- a/fs/smbfs/symlink.c +++ b/fs/smbfs/symlink.c @@ -34,7 +34,7 @@ int smb_symlink(struct inode *inode, str return smb_proc_symlink(server_from_dentry(dentry), dentry, oldname); } -static void *smb_follow_link(struct dentry *dentry, struct nameidata *nd) +static void *smb_follow_link(struct vfsmount *mnt, struct dentry *dentry, struct nameidata *nd) { char *link = __getname(); DEBUG1("followlink of %s/%s\n", DENTRY_PATH(dentry)); diff --git a/fs/sysfs/symlink.c b/fs/sysfs/symlink.c index de402fa..2cf51b0 100644 --- a/fs/sysfs/symlink.c +++ b/fs/sysfs/symlink.c @@ -151,7 +151,7 @@ static int sysfs_getlink(struct dentry * } -static void *sysfs_follow_link(struct dentry *dentry, struct nameidata *nd) +static void *sysfs_follow_link(struct vfsmount *mnt, struct dentry *dentry, struct nameidata *nd) { int error = -ENOMEM; unsigned long page = get_zeroed_page(GFP_KERNEL); diff --git a/fs/sysv/symlink.c b/fs/sysv/symlink.c index b85ce61..c5def18 100644 --- a/fs/sysv/symlink.c +++ b/fs/sysv/symlink.c @@ -8,7 +8,7 @@ #include "sysv.h" #include -static void *sysv_follow_link(struct dentry *dentry, struct nameidata *nd) +static void *sysv_follow_link(struct vfsmount *mnt, struct dentry *dentry, struct nameidata *nd) { nd_set_link(nd, (char *)SYSV_I(dentry->d_inode)->i_data); return NULL; diff --git a/fs/ufs/symlink.c b/fs/ufs/symlink.c index 337512e..b0da3c1 100644 --- a/fs/ufs/symlink.c +++ b/fs/ufs/symlink.c @@ -29,7 +29,7 @@ #include #include -static void *ufs_follow_link(struct dentry *dentry, struct nameidata *nd) +static void *ufs_follow_link(struct vfsmount *mnt, struct dentry *dentry, struct nameidata *nd) { struct ufs_inode_info *p = UFS_I(dentry->d_inode); nd_set_link(nd, (char*)p->i_u1.i_symlink); diff --git a/fs/xfs/linux-2.6/xfs_iops.c b/fs/xfs/linux-2.6/xfs_iops.c index 77708a8..a91a057 100644 --- a/fs/xfs/linux-2.6/xfs_iops.c +++ b/fs/xfs/linux-2.6/xfs_iops.c @@ -374,6 +374,7 @@ linvfs_rename( */ STATIC void * linvfs_follow_link( + struct vfsmount *mnt, struct dentry *dentry, struct nameidata *nd) { diff --git a/include/linux/fs.h b/include/linux/fs.h index e0b77c5..3f392de 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -985,7 +985,7 @@ struct inode_operations { int (*rename) (struct inode *, struct dentry *, struct inode *, struct dentry *); int (*readlink) (struct dentry *, char __user *,int); - void * (*follow_link) (struct dentry *, struct nameidata *); + void * (*follow_link) (struct vfsmount *, struct dentry *, struct nameidata *); void (*put_link) (struct dentry *, struct nameidata *, void *); void (*truncate) (struct inode *); int (*permission) (struct inode *, int, struct nameidata *); @@ -1593,7 +1593,7 @@ extern struct file_operations generic_ro extern int vfs_readlink(struct dentry *, char __user *, int, const char *); extern int vfs_follow_link(struct nameidata *, const char *); extern int page_readlink(struct dentry *, char __user *, int); -extern void *page_follow_link_light(struct dentry *, struct nameidata *); +extern void *page_follow_link_light(struct vfsmount *,struct dentry *, struct nameidata *); extern void page_put_link(struct dentry *, struct nameidata *, void *); extern int page_symlink(struct inode *inode, const char *symname, int len); extern struct inode_operations page_symlink_inode_operations; diff --git a/include/linux/pspace.h b/include/linux/pspace.h index deeaac8..3d61ba8 100644 --- a/include/linux/pspace.h +++ b/include/linux/pspace.h @@ -12,12 +12,16 @@ struct pidmap #define PIDMAP_ENTRIES ((PID_MAX_LIMIT + 8*PAGE_SIZE - 1)/PAGE_SIZE/8) +#if 0 struct dentry; +#endif struct pspace { atomic_t count; struct pspace *parent; +#if 0 struct dentry *proc_root; +#endif int nr_threads; int last_pid; int offset; diff --git a/include/linux/security.h b/include/linux/security.h index 627382e..8efc80d 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -327,6 +327,7 @@ struct swap_info_struct; * Return 0 if permission is granted. * @inode_follow_link: * Check permission to follow a symbolic link when looking up a pathname. + * @vfsmount containts the mountpoint the link is on. * @dentry contains the dentry structure for the link. * @nd contains the nameidata structure for the parent directory. * Return 0 if permission is granted. @@ -1079,7 +1080,7 @@ struct security_operations { int (*inode_rename) (struct inode *old_dir, struct dentry *old_dentry, struct inode *new_dir, struct dentry *new_dentry); int (*inode_readlink) (struct dentry *dentry); - int (*inode_follow_link) (struct dentry *dentry, struct nameidata *nd); + int (*inode_follow_link) (struct vfsmount *mnt, struct dentry *dentry, struct nameidata *nd); int (*inode_permission) (struct inode *inode, int mask, struct nameidata *nd); int (*inode_setattr) (struct dentry *dentry, struct iattr *attr); int (*inode_getattr) (struct vfsmount *mnt, struct dentry *dentry); @@ -1504,12 +1505,12 @@ static inline int security_inode_readlin return security_ops->inode_readlink (dentry); } -static inline int security_inode_follow_link (struct dentry *dentry, +static inline int security_inode_follow_link (struct vfsmount *mnt, struct dentry *dentry, struct nameidata *nd) { if (unlikely (IS_PRIVATE (dentry->d_inode))) return 0; - return security_ops->inode_follow_link (dentry, nd); + return security_ops->inode_follow_link (mnt, dentry, nd); } static inline int security_inode_permission (struct inode *inode, int mask, @@ -2170,7 +2171,7 @@ static inline int security_inode_readlin return 0; } -static inline int security_inode_follow_link (struct dentry *dentry, +static inline int security_inode_follow_link (struct vfsmount *mnt, struct dentry *dentry, struct nameidata *nd) { return 0; diff --git a/kernel/pid.c b/kernel/pid.c index 615ed9b..118132f 100644 --- a/kernel/pid.c +++ b/kernel/pid.c @@ -292,10 +292,12 @@ static struct pspace *new_pspace(int pid pspace->offset = offset; pspace->min = 1; pspace->max = pids; +#if 0 if (proc_pspace_root_dentry(pspace)) { kfree(pspace); return NULL; } +#endif for (i = 0; i < pages; i++) { atomic_set(&pspace->pidmap[i].nr_free, BITS_PER_PAGE); pspace->pidmap[i].page = NULL; diff --git a/mm/shmem.c b/mm/shmem.c index ea064d8..c99ab6d 100644 --- a/mm/shmem.c +++ b/mm/shmem.c @@ -1792,13 +1792,13 @@ static int shmem_symlink(struct inode *d return 0; } -static void *shmem_follow_link_inline(struct dentry *dentry, struct nameidata *nd) +static void *shmem_follow_link_inline(struct vfsmount *mnt, struct dentry *dentry, struct nameidata *nd) { nd_set_link(nd, (char *)SHMEM_I(dentry->d_inode)); return NULL; } -static void *shmem_follow_link(struct dentry *dentry, struct nameidata *nd) +static void *shmem_follow_link(struct vfsmount *mnt, struct dentry *dentry, struct nameidata *nd) { struct page *page = NULL; int res = shmem_getpage(dentry->d_inode, 0, &page, SGP_READ, NULL); diff --git a/security/dummy.c b/security/dummy.c index 9623a61..340a4ca 100644 --- a/security/dummy.c +++ b/security/dummy.c @@ -317,7 +317,7 @@ static int dummy_inode_readlink (struct return 0; } -static int dummy_inode_follow_link (struct dentry *dentry, +static int dummy_inode_follow_link (struct vfsmount *mnt, struct dentry *dentry, struct nameidata *nameidata) { return 0; diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index b13be15..d66fec5 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -2074,11 +2074,11 @@ static int selinux_inode_readlink(struct return dentry_has_perm(current, NULL, dentry, FILE__READ); } -static int selinux_inode_follow_link(struct dentry *dentry, struct nameidata *nameidata) +static int selinux_inode_follow_link(struct vfsmount *mnt, struct dentry *dentry, struct nameidata *nameidata) { int rc; - rc = secondary_ops->inode_follow_link(dentry,nameidata); + rc = secondary_ops->inode_follow_link(mnt,dentry,nameidata); if (rc) return rc; return dentry_has_perm(current, NULL, dentry, FILE__READ); -- 1.0.GIT