From: Christoph Hellwig Subject: [PATCH 1/2] add a vfs_permission helper Date: Tue, 1 Nov 2005 03:03:12 +0100 Message-ID: <20051101020312.GA23020@lst.de> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Cc: linux-fsdevel@vger.kernel.org Return-path: Received: from verein.lst.de ([213.95.11.210]:42665 "EHLO mail.lst.de") by vger.kernel.org with ESMTP id S964913AbVKACDS (ORCPT ); Mon, 31 Oct 2005 21:03:18 -0500 To: akpm@osdl.org Content-Disposition: inline Sender: linux-fsdevel-owner@vger.kernel.org List-Id: linux-fsdevel.vger.kernel.org Most permission() calls have a struct nameidata * available. This helper takes that as an argument and thus makes sure we pass it down for lookup intents and prepares for per-mount read-only support where we need a struct vfsmount for checking whether a file is writeable. Signed-off-by: Christoph Hellwig Index: linux-2.6/fs/exec.c =================================================================== --- linux-2.6.orig/fs/exec.c 2005-10-31 14:42:07.000000000 +0100 +++ linux-2.6/fs/exec.c 2005-10-31 17:55:00.000000000 +0100 @@ -134,7 +134,7 @@ if (!S_ISREG(nd.dentry->d_inode->i_mode)) goto exit; - error = permission(nd.dentry->d_inode, MAY_READ | MAY_EXEC, &nd); + error = vfs_permission(&nd, MAY_READ | MAY_EXEC); if (error) goto exit; @@ -494,7 +494,7 @@ file = ERR_PTR(-EACCES); if (!(nd.mnt->mnt_flags & MNT_NOEXEC) && S_ISREG(inode->i_mode)) { - int err = permission(inode, MAY_EXEC, &nd); + int err = vfs_permission(&nd, MAY_EXEC); if (!err && !(inode->i_mode & 0111)) err = -EACCES; file = ERR_PTR(err); Index: linux-2.6/fs/inotify.c =================================================================== --- linux-2.6.orig/fs/inotify.c 2005-10-31 14:42:07.000000000 +0100 +++ linux-2.6/fs/inotify.c 2005-10-31 14:42:45.000000000 +0100 @@ -372,7 +372,7 @@ if (error) return error; /* you can only watch an inode if you have read permissions on it */ - error = permission(nd->dentry->d_inode, MAY_READ, NULL); + error = vfs_permission(nd, MAY_READ); if (error) path_release(nd); return error; Index: linux-2.6/fs/namei.c =================================================================== --- linux-2.6.orig/fs/namei.c 2005-10-31 14:42:07.000000000 +0100 +++ linux-2.6/fs/namei.c 2005-10-31 17:55:15.000000000 +0100 @@ -256,6 +256,21 @@ return security_inode_permission(inode, mask, nd); } +/** + * vfs_permission - check for access rights to a given path + * @nd: lookup result that describes the path + * @mask: right to check for (%MAY_READ, %MAY_WRITE, %MAY_EXEC) + * + * Used to check for read/write/execute permissions on a path. + * We use "fsuid" for this, letting us set arbitrary permissions + * for filesystem access without changing the "normal" uids which + * are used for other things. + */ +int vfs_permission(struct nameidata *nd, int mask) +{ + return permission(nd->dentry->d_inode, mask, nd); +} + /* * get_write_access() gets write permission for a file. * put_write_access() releases this write permission. @@ -765,9 +780,8 @@ nd->flags |= LOOKUP_CONTINUE; err = exec_permission_lite(inode, nd); - if (err == -EAGAIN) { - err = permission(inode, MAY_EXEC, nd); - } + if (err == -EAGAIN) + err = vfs_permission(nd, MAY_EXEC); if (err) break; @@ -1407,7 +1421,7 @@ if (S_ISDIR(inode->i_mode) && (flag & FMODE_WRITE)) return -EISDIR; - error = permission(inode, acc_mode, nd); + error = vfs_permission(nd, acc_mode); if (error) return error; @@ -2536,6 +2550,7 @@ EXPORT_SYMBOL(path_release); EXPORT_SYMBOL(path_walk); EXPORT_SYMBOL(permission); +EXPORT_SYMBOL(vfs_permission); EXPORT_SYMBOL(unlock_rename); EXPORT_SYMBOL(vfs_create); EXPORT_SYMBOL(vfs_follow_link); Index: linux-2.6/fs/namespace.c =================================================================== --- linux-2.6.orig/fs/namespace.c 2005-10-31 14:42:07.000000000 +0100 +++ linux-2.6/fs/namespace.c 2005-10-31 14:42:45.000000000 +0100 @@ -516,7 +516,7 @@ if (current->uid != nd->dentry->d_inode->i_uid) return -EPERM; } - if (permission(nd->dentry->d_inode, MAY_WRITE, nd)) + if (vfs_permission(nd, MAY_WRITE)) return -EPERM; return 0; #endif Index: linux-2.6/fs/open.c =================================================================== --- linux-2.6.orig/fs/open.c 2005-10-31 14:42:07.000000000 +0100 +++ linux-2.6/fs/open.c 2005-10-31 17:55:00.000000000 +0100 @@ -236,7 +236,7 @@ if (!S_ISREG(inode->i_mode)) goto dput_and_out; - error = permission(inode,MAY_WRITE,&nd); + error = vfs_permission(&nd, MAY_WRITE); if (error) goto dput_and_out; @@ -390,7 +390,7 @@ goto dput_and_out; if (current->fsuid != inode->i_uid && - (error = permission(inode,MAY_WRITE,&nd)) != 0) + (error = vfs_permission(&nd, MAY_WRITE)) != 0) goto dput_and_out; } down(&inode->i_sem); @@ -443,7 +443,7 @@ goto dput_and_out; if (current->fsuid != inode->i_uid && - (error = permission(inode,MAY_WRITE,&nd)) != 0) + (error = vfs_permission(&nd, MAY_WRITE)) != 0) goto dput_and_out; } down(&inode->i_sem); @@ -502,7 +502,7 @@ res = __user_walk(filename, LOOKUP_FOLLOW|LOOKUP_ACCESS, &nd); if (!res) { - res = permission(nd.dentry->d_inode, mode, &nd); + res = vfs_permission(&nd, mode); /* SuS v2 requires we report a read only fs too */ if(!res && (mode & S_IWOTH) && IS_RDONLY(nd.dentry->d_inode) && !special_file(nd.dentry->d_inode->i_mode)) @@ -526,7 +526,7 @@ if (error) goto out; - error = permission(nd.dentry->d_inode,MAY_EXEC,&nd); + error = vfs_permission(&nd, MAY_EXEC); if (error) goto dput_and_out; @@ -577,7 +577,7 @@ if (error) goto out; - error = permission(nd.dentry->d_inode,MAY_EXEC,&nd); + error = vfs_permission(&nd, MAY_EXEC); if (error) goto dput_and_out; Index: linux-2.6/include/linux/fs.h =================================================================== --- linux-2.6.orig/include/linux/fs.h 2005-10-31 14:42:07.000000000 +0100 +++ linux-2.6/include/linux/fs.h 2005-10-31 17:55:00.000000000 +0100 @@ -862,6 +862,7 @@ /* * VFS helper functions.. */ +extern int vfs_permission(struct nameidata *, int); extern int vfs_create(struct inode *, struct dentry *, int, struct nameidata *); extern int vfs_mkdir(struct inode *, struct dentry *, int); extern int vfs_mknod(struct inode *, struct dentry *, int, dev_t); Index: linux-2.6/net/unix/af_unix.c =================================================================== --- linux-2.6.orig/net/unix/af_unix.c 2005-10-31 14:42:07.000000000 +0100 +++ linux-2.6/net/unix/af_unix.c 2005-10-31 14:42:45.000000000 +0100 @@ -676,7 +676,7 @@ err = path_lookup(sunname->sun_path, LOOKUP_FOLLOW, &nd); if (err) goto fail; - err = permission(nd.dentry->d_inode,MAY_WRITE, &nd); + err = vfs_permission(&nd, MAY_WRITE); if (err) goto put_fail;