[PATCH] add a file_permission helper
Christoph Hellwig [Wed, 9 Nov 2005 05:35:04 +0000 (21:35 -0800)]
A few more callers of permission() just want to check for a different access
pattern on an already open file.  This patch adds a wrapper for permission()
that takes a file in preparation of per-mount read-only support and to clean
up the callers a little.  The helper is not intended for new code, everything
without the interface set in stone should use vfs_permission()

Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>

drivers/block/floppy.c
fs/binfmt_misc.c
fs/exec.c
fs/namei.c
fs/ncpfs/ioctl.c
fs/open.c
fs/udf/file.c
include/linux/fs.h

index dd1935d..28002de 100644 (file)
@@ -3776,8 +3776,7 @@ static int floppy_open(struct inode *inode, struct file *filp)
        /* Allow ioctls if we have write-permissions even if read-only open.
         * Needed so that programs such as fdrawcmd still can work on write
         * protected disks */
-       if (filp->f_mode & 2
-           || permission(filp->f_dentry->d_inode, 2, NULL) == 0)
+       if ((filp->f_mode & FMODE_WRITE) || !file_permission(filp, MAY_WRITE))
                filp->private_data = (void *)8;
 
        if (UFDCS->rawcmd == 1)
index 8ae0db6..2568eb4 100644 (file)
@@ -150,7 +150,7 @@ static int load_misc_binary(struct linux_binprm *bprm, struct pt_regs *regs)
 
                /* if the binary is not readable than enforce mm->dumpable=0
                   regardless of the interpreter's permissions */
-               if (permission(bprm->file->f_dentry->d_inode, MAY_READ, NULL))
+               if (file_permission(bprm->file, MAY_READ))
                        bprm->interp_flags |= BINPRM_FLAGS_ENFORCE_NONDUMP;
 
                allow_write_access(bprm->file);
index 7bbb781..c466fec 100644 (file)
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -896,7 +896,7 @@ int flush_old_exec(struct linux_binprm * bprm)
        flush_thread();
 
        if (bprm->e_uid != current->euid || bprm->e_gid != current->egid || 
-           permission(bprm->file->f_dentry->d_inode,MAY_READ, NULL) ||
+           file_permission(bprm->file, MAY_READ) ||
            (bprm->interp_flags & BINPRM_FLAGS_ENFORCE_NONDUMP)) {
                suid_keys(current);
                current->mm->dumpable = suid_dumpable;
index 25e4ab4..b69f6eb 100644 (file)
@@ -271,6 +271,23 @@ int vfs_permission(struct nameidata *nd, int mask)
        return permission(nd->dentry->d_inode, mask, nd);
 }
 
+/**
+ * file_permission  -  check for additional access rights to a given file
+ * @file:      file to check access rights for
+ * @mask:      right to check for (%MAY_READ, %MAY_WRITE, %MAY_EXEC)
+ *
+ * Used to check for read/write/execute permissions on an already opened
+ * file.
+ *
+ * Note:
+ *     Do not use this function in new code.  All access checks should
+ *     be done using vfs_permission().
+ */
+int file_permission(struct file *file, int mask)
+{
+       return permission(file->f_dentry->d_inode, mask, NULL);
+}
+
 /*
  * get_write_access() gets write permission for a file.
  * put_write_access() releases this write permission.
@@ -2551,6 +2568,7 @@ EXPORT_SYMBOL(path_release);
 EXPORT_SYMBOL(path_walk);
 EXPORT_SYMBOL(permission);
 EXPORT_SYMBOL(vfs_permission);
+EXPORT_SYMBOL(file_permission);
 EXPORT_SYMBOL(unlock_rename);
 EXPORT_SYMBOL(vfs_create);
 EXPORT_SYMBOL(vfs_follow_link);
index 88df793..fd3efdc 100644 (file)
 #define NCP_PACKET_SIZE_INTERNAL 65536
 
 static int
-ncp_get_fs_info(struct ncp_server* server, struct inode* inode, struct ncp_fs_info __user *arg)
+ncp_get_fs_info(struct ncp_server * server, struct file *file,
+               struct ncp_fs_info __user *arg)
 {
+       struct inode *inode = file->f_dentry->d_inode;
        struct ncp_fs_info info;
 
-       if ((permission(inode, MAY_WRITE, NULL) != 0)
+       if ((file_permission(file, MAY_WRITE) != 0)
            && (current->uid != server->m.mounted_uid)) {
                return -EACCES;
        }
@@ -58,11 +60,13 @@ ncp_get_fs_info(struct ncp_server* server, struct inode* inode, struct ncp_fs_in
 }
 
 static int
-ncp_get_fs_info_v2(struct ncp_server* server, struct inode* inode, struct ncp_fs_info_v2 __user * arg)
+ncp_get_fs_info_v2(struct ncp_server * server, struct file *file,
+                  struct ncp_fs_info_v2 __user * arg)
 {
+       struct inode *inode = file->f_dentry->d_inode;
        struct ncp_fs_info_v2 info2;
 
-       if ((permission(inode, MAY_WRITE, NULL) != 0)
+       if ((file_permission(file, MAY_WRITE) != 0)
            && (current->uid != server->m.mounted_uid)) {
                return -EACCES;
        }
@@ -190,7 +194,7 @@ int ncp_ioctl(struct inode *inode, struct file *filp,
        switch (cmd) {
        case NCP_IOC_NCPREQUEST:
 
-               if ((permission(inode, MAY_WRITE, NULL) != 0)
+               if ((file_permission(filp, MAY_WRITE) != 0)
                    && (current->uid != server->m.mounted_uid)) {
                        return -EACCES;
                }
@@ -245,16 +249,16 @@ int ncp_ioctl(struct inode *inode, struct file *filp,
                return ncp_conn_logged_in(inode->i_sb);
 
        case NCP_IOC_GET_FS_INFO:
-               return ncp_get_fs_info(server, inode, argp);
+               return ncp_get_fs_info(server, filp, argp);
 
        case NCP_IOC_GET_FS_INFO_V2:
-               return ncp_get_fs_info_v2(server, inode, argp);
+               return ncp_get_fs_info_v2(server, filp, argp);
 
        case NCP_IOC_GETMOUNTUID2:
                {
                        unsigned long tmp = server->m.mounted_uid;
 
-                       if (   (permission(inode, MAY_READ, NULL) != 0)
+                       if ((file_permission(filp, MAY_READ) != 0)
                            && (current->uid != server->m.mounted_uid))
                        {
                                return -EACCES;
@@ -268,7 +272,7 @@ int ncp_ioctl(struct inode *inode, struct file *filp,
                {
                        struct ncp_setroot_ioctl sr;
 
-                       if (   (permission(inode, MAY_READ, NULL) != 0)
+                       if ((file_permission(filp, MAY_READ) != 0)
                            && (current->uid != server->m.mounted_uid))
                        {
                                return -EACCES;
@@ -343,7 +347,7 @@ int ncp_ioctl(struct inode *inode, struct file *filp,
 
 #ifdef CONFIG_NCPFS_PACKET_SIGNING     
        case NCP_IOC_SIGN_INIT:
-               if ((permission(inode, MAY_WRITE, NULL) != 0)
+               if ((file_permission(filp, MAY_WRITE) != 0)
                    && (current->uid != server->m.mounted_uid))
                {
                        return -EACCES;
@@ -366,7 +370,7 @@ int ncp_ioctl(struct inode *inode, struct file *filp,
                return 0;               
                
         case NCP_IOC_SIGN_WANTED:
-               if (   (permission(inode, MAY_READ, NULL) != 0)
+               if ((file_permission(filp, MAY_READ) != 0)
                    && (current->uid != server->m.mounted_uid))
                {
                        return -EACCES;
@@ -379,7 +383,7 @@ int ncp_ioctl(struct inode *inode, struct file *filp,
                {
                        int newstate;
 
-                       if (   (permission(inode, MAY_WRITE, NULL) != 0)
+                       if ((file_permission(filp, MAY_WRITE) != 0)
                            && (current->uid != server->m.mounted_uid))
                        {
                                return -EACCES;
@@ -400,7 +404,7 @@ int ncp_ioctl(struct inode *inode, struct file *filp,
 
 #ifdef CONFIG_NCPFS_IOCTL_LOCKING
        case NCP_IOC_LOCKUNLOCK:
-               if (   (permission(inode, MAY_WRITE, NULL) != 0)
+               if ((file_permission(filp, MAY_WRITE) != 0)
                    && (current->uid != server->m.mounted_uid))
                {
                        return -EACCES;
@@ -605,7 +609,7 @@ outrel:
 #endif /* CONFIG_NCPFS_NLS */
 
        case NCP_IOC_SETDENTRYTTL:
-               if ((permission(inode, MAY_WRITE, NULL) != 0) &&
+               if ((file_permission(filp, MAY_WRITE) != 0) &&
                                 (current->uid != server->m.mounted_uid))
                        return -EACCES;
                {
@@ -635,7 +639,7 @@ outrel:
            so we have this out of switch */
        if (cmd == NCP_IOC_GETMOUNTUID) {
                __kernel_uid_t uid = 0;
-               if ((permission(inode, MAY_READ, NULL) != 0)
+               if ((file_permission(filp, MAY_READ) != 0)
                    && (current->uid != server->m.mounted_uid)) {
                        return -EACCES;
                }
index baffc08..f53a5b9 100644 (file)
--- a/fs/open.c
+++ b/fs/open.c
@@ -563,7 +563,7 @@ asmlinkage long sys_fchdir(unsigned int fd)
        if (!S_ISDIR(inode->i_mode))
                goto out_putf;
 
-       error = permission(inode, MAY_EXEC, NULL);
+       error = file_permission(file, MAY_EXEC);
        if (!error)
                set_fs_pwd(current->fs, mnt, dentry);
 out_putf:
index bb40d63..01f520c 100644 (file)
@@ -186,7 +186,7 @@ int udf_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
 {
        int result = -EINVAL;
 
-       if ( permission(inode, MAY_READ, NULL) != 0 )
+       if ( file_permission(filp, MAY_READ) != 0 )
        {
                udf_debug("no permission to access inode %lu\n",
                                                inode->i_ino);
index c3b8c1d..cc35b6a 100644 (file)
@@ -890,6 +890,11 @@ extern int vfs_rename(struct inode *, struct dentry *, struct inode *, struct de
 extern void dentry_unhash(struct dentry *dentry);
 
 /*
+ * VFS file helper functions.
+ */
+extern int file_permission(struct file *, int);
+
+/*
  * File types
  *
  * NOTE! These match bits 12..15 of stat.st_mode