From: Paolo 'B. G. <bla...@ya...> - 2005-09-18 14:23:21
|
From: Paolo 'Blaisorblade' Giarrusso <bla...@ya...>, Al Viro Procfs uses a special permission method in some cases, so we can't use the generic one, and must call instead the inode's one if it's not null (only some inodes use a custom method). It seems that this method is used to avoid a chroot'ed process to escape its chroot by accessing another process's root/cwd through procfs (both by a quick read of the code and by testing on the host), like in "cd /proc/1/root". I've not added a ->permission operation on symlink, as there is no procfs symlink using it, and I wonder if symlink can have permissions set at all (guess not). If you disagree, just add it (hppfs_permission() handles null pointers gracefully). Note: I've cared to use the proc inode (I missed that in the beginning) - since the dentry is always created by the underlying ->lookup this should be safe - or not? I've gone to do some checking, and since we pass to it a procfs inode, referring to the procfs superblock, it seems that yes, we're fine. Signed-off-by: Paolo 'Blaisorblade' Giarrusso <bla...@ya...> --- fs/hppfs/hppfs_kern.c | 16 ++++++++++++++++ 1 files changed, 16 insertions(+), 0 deletions(-) diff --git a/fs/hppfs/hppfs_kern.c b/fs/hppfs/hppfs_kern.c --- a/fs/hppfs/hppfs_kern.c +++ b/fs/hppfs/hppfs_kern.c @@ -214,7 +214,22 @@ static struct dentry *hppfs_lookup(struc return(ERR_PTR(err)); } +static int hppfs_permission(struct inode *inode, int mask, struct nameidata *nd) +{ + struct inode *proc_inode; + int (*permission) (struct inode *, int, struct nameidata *); + + proc_inode = HPPFS_I(inode)->proc_dentry->d_inode; + permission = proc_inode->i_op->permission; + + if (permission == NULL) + return generic_permission(inode, mask, NULL); + + return (*permission)(proc_inode, mask, nd); +} + static struct inode_operations hppfs_file_iops = { + .permission = hppfs_permission, }; /* Pass down ppos when you're being called from userspace. @@ -779,6 +794,7 @@ static void* hppfs_follow_link(struct de } static struct inode_operations hppfs_dir_iops = { + .permission = hppfs_permission, .lookup = hppfs_lookup, }; |