[PATCH] sanitize ->permission() prototype
authorAl Viro <viro@zeniv.linux.org.uk>
Wed, 16 Jul 2008 01:03:57 +0000 (21:03 -0400)
committerAl Viro <viro@zeniv.linux.org.uk>
Sun, 27 Jul 2008 00:53:14 +0000 (20:53 -0400)
* kill nameidata * argument; map the 3 bits in ->flags anybody cares
  about to new MAY_... ones and pass with the mask.
* kill redundant gfs2_iop_permission()
* sanitize ecryptfs_permission()
* fix remaining places where ->permission() instances might barf on new
  MAY_... found in mask.

The obvious next target in that direction is permission(9)

folded fix for nfs_permission() breakage from Miklos Szeredi <mszeredi@suse.cz>

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
38 files changed:
fs/afs/internal.h
fs/afs/security.c
fs/bad_inode.c
fs/cifs/cifsfs.c
fs/coda/dir.c
fs/coda/pioctl.c
fs/ecryptfs/inode.c
fs/ext2/acl.c
fs/ext2/acl.h
fs/ext3/acl.c
fs/ext3/acl.h
fs/ext4/acl.c
fs/ext4/acl.h
fs/fuse/dir.c
fs/gfs2/ops_inode.c
fs/hfs/inode.c
fs/hfsplus/inode.c
fs/hostfs/hostfs_kern.c
fs/jffs2/acl.c
fs/jffs2/acl.h
fs/jfs/acl.c
fs/jfs/jfs_acl.h
fs/namei.c
fs/nfs/dir.c
fs/ocfs2/file.c
fs/ocfs2/file.h
fs/proc/base.c
fs/proc/proc_sysctl.c
fs/reiserfs/xattr.c
fs/smbfs/file.c
fs/xfs/linux-2.6/xfs_iops.c
include/linux/coda_linux.h
include/linux/fs.h
include/linux/nfs_fs.h
include/linux/reiserfs_xattr.h
include/linux/shmem_fs.h
kernel/sysctl.c
mm/shmem_acl.c

index 7102824ba8479c6e2d006816fb3555311d56df61..3cb6920ff30bc6ee7f22a98a390b04119d1ae81c 100644 (file)
@@ -469,8 +469,6 @@ extern bool afs_cm_incoming_call(struct afs_call *);
 extern const struct inode_operations afs_dir_inode_operations;
 extern const struct file_operations afs_dir_file_operations;
 
-extern int afs_permission(struct inode *, int, struct nameidata *);
-
 /*
  * file.c
  */
@@ -605,7 +603,7 @@ extern void afs_clear_permits(struct afs_vnode *);
 extern void afs_cache_permit(struct afs_vnode *, struct key *, long);
 extern void afs_zap_permits(struct rcu_head *);
 extern struct key *afs_request_key(struct afs_cell *);
-extern int afs_permission(struct inode *, int, struct nameidata *);
+extern int afs_permission(struct inode *, int);
 
 /*
  * server.c
index 3bcbeceba1bb6a778b08328ea459023927a2ccc8..3ef504370034c2311fdd50f631856ac95ab76903 100644 (file)
@@ -284,7 +284,7 @@ static int afs_check_permit(struct afs_vnode *vnode, struct key *key,
  * - AFS ACLs are attached to directories only, and a file is controlled by its
  *   parent directory's ACL
  */
-int afs_permission(struct inode *inode, int mask, struct nameidata *nd)
+int afs_permission(struct inode *inode, int mask)
 {
        struct afs_vnode *vnode = AFS_FS_I(inode);
        afs_access_t uninitialized_var(access);
index f1c2ea8342f514c974539dd5a676b650efbf6e5f..5f1538c03b1bbeb068c089146cc28fc502bb0d83 100644 (file)
@@ -243,8 +243,7 @@ static int bad_inode_readlink(struct dentry *dentry, char __user *buffer,
        return -EIO;
 }
 
-static int bad_inode_permission(struct inode *inode, int mask,
-                       struct nameidata *nd)
+static int bad_inode_permission(struct inode *inode, int mask)
 {
        return -EIO;
 }
index fe5f6809cba6e75322511b10b4066c3e4d61551f..1ec7076f7b241b7a86d182043db5debf36fdd977 100644 (file)
@@ -267,7 +267,7 @@ cifs_statfs(struct dentry *dentry, struct kstatfs *buf)
        return 0;
 }
 
-static int cifs_permission(struct inode *inode, int mask, struct nameidata *nd)
+static int cifs_permission(struct inode *inode, int mask)
 {
        struct cifs_sb_info *cifs_sb;
 
index 3d2580e00a3e272e0cfe04103c98466e2daa15e7..c5916228243c1516b2d62e6b06cea208523a09ac 100644 (file)
@@ -137,9 +137,11 @@ exit:
 }
 
 
-int coda_permission(struct inode *inode, int mask, struct nameidata *nd)
+int coda_permission(struct inode *inode, int mask)
 {
         int error = 0;
+
+       mask &= MAY_READ | MAY_WRITE | MAY_EXEC;
  
        if (!mask)
                return 0; 
index c21a1f552a63bf0ca7ef5d09905a326036f0e844..c38a98974fb0d0797448481c3da94f9eddb53723 100644 (file)
@@ -24,8 +24,7 @@
 #include <linux/coda_psdev.h>
 
 /* pioctl ops */
-static int coda_ioctl_permission(struct inode *inode, int mask,
-                                struct nameidata *nd);
+static int coda_ioctl_permission(struct inode *inode, int mask);
 static int coda_pioctl(struct inode * inode, struct file * filp, 
                        unsigned int cmd, unsigned long user_data);
 
@@ -42,8 +41,7 @@ const struct file_operations coda_ioctl_operations = {
 };
 
 /* the coda pioctl inode ops */
-static int coda_ioctl_permission(struct inode *inode, int mask,
-                                struct nameidata *nd)
+static int coda_ioctl_permission(struct inode *inode, int mask)
 {
         return 0;
 }
index d755455e3bff03aaffd1fd95715265b9f28f931f..32f4228efcd59417eefbc6cb69f92942cba07ad8 100644 (file)
@@ -830,22 +830,9 @@ out:
 }
 
 static int
-ecryptfs_permission(struct inode *inode, int mask, struct nameidata *nd)
+ecryptfs_permission(struct inode *inode, int mask)
 {
-       int rc;
-
-        if (nd) {
-               struct vfsmount *vfsmnt_save = nd->path.mnt;
-               struct dentry *dentry_save = nd->path.dentry;
-
-               nd->path.mnt = ecryptfs_dentry_to_lower_mnt(nd->path.dentry);
-               nd->path.dentry = ecryptfs_dentry_to_lower(nd->path.dentry);
-               rc = permission(ecryptfs_inode_to_lower(inode), mask, nd);
-               nd->path.mnt = vfsmnt_save;
-               nd->path.dentry = dentry_save;
-        } else
-               rc = permission(ecryptfs_inode_to_lower(inode), mask, NULL);
-        return rc;
+       return permission(ecryptfs_inode_to_lower(inode), mask, NULL);
 }
 
 /**
index e58669e1b87c6bab0e0a0ac8677713b5b2f3fbb8..ae8c4f850b27d0e83e28e684a07637a992abbe69 100644 (file)
@@ -294,7 +294,7 @@ ext2_check_acl(struct inode *inode, int mask)
 }
 
 int
-ext2_permission(struct inode *inode, int mask, struct nameidata *nd)
+ext2_permission(struct inode *inode, int mask)
 {
        return generic_permission(inode, mask, ext2_check_acl);
 }
index 0bde85bafe386eb47187919a8409e0231b4f5298..b42cf578554b5fd10ec8c290ea3fca3af05f9020 100644 (file)
@@ -58,7 +58,7 @@ static inline int ext2_acl_count(size_t size)
 #define EXT2_ACL_NOT_CACHED ((void *)-1)
 
 /* acl.c */
-extern int ext2_permission (struct inode *, int, struct nameidata *);
+extern int ext2_permission (struct inode *, int);
 extern int ext2_acl_chmod (struct inode *);
 extern int ext2_init_acl (struct inode *, struct inode *);
 
index a754d1848173af1b0d5e899d29c0a914211a134a..b60bb241880c86f50420e13411dc19b1148e1a51 100644 (file)
@@ -299,7 +299,7 @@ ext3_check_acl(struct inode *inode, int mask)
 }
 
 int
-ext3_permission(struct inode *inode, int mask, struct nameidata *nd)
+ext3_permission(struct inode *inode, int mask)
 {
        return generic_permission(inode, mask, ext3_check_acl);
 }
index 0d1e6279cbfd5799a11f27f774fbcdaf8bd397fb..42da16b8cac0a82d1bdd06a18c178308068e8d08 100644 (file)
@@ -58,7 +58,7 @@ static inline int ext3_acl_count(size_t size)
 #define EXT3_ACL_NOT_CACHED ((void *)-1)
 
 /* acl.c */
-extern int ext3_permission (struct inode *, int, struct nameidata *);
+extern int ext3_permission (struct inode *, int);
 extern int ext3_acl_chmod (struct inode *);
 extern int ext3_init_acl (handle_t *, struct inode *, struct inode *);
 
index 3c8dab880d91f1bb38247d44d605f2bc3943a90e..c7d04e165446dfc5391930b24ce2a1d3280e71d1 100644 (file)
@@ -299,7 +299,7 @@ ext4_check_acl(struct inode *inode, int mask)
 }
 
 int
-ext4_permission(struct inode *inode, int mask, struct nameidata *nd)
+ext4_permission(struct inode *inode, int mask)
 {
        return generic_permission(inode, mask, ext4_check_acl);
 }
index 26a5c1abf147bf9690f091baba133ec5eab7cf00..cd2b855a07d669988f817f6e7415088b8dcefed6 100644 (file)
@@ -58,7 +58,7 @@ static inline int ext4_acl_count(size_t size)
 #define EXT4_ACL_NOT_CACHED ((void *)-1)
 
 /* acl.c */
-extern int ext4_permission (struct inode *, int, struct nameidata *);
+extern int ext4_permission (struct inode *, int);
 extern int ext4_acl_chmod (struct inode *);
 extern int ext4_init_acl (handle_t *, struct inode *, struct inode *);
 
index 51d0035ff07e3a59037324ef256eb6b849163deb..48a7934cb9504ca7a9e295a2b82978a6b9822a4f 100644 (file)
@@ -898,7 +898,7 @@ static int fuse_access(struct inode *inode, int mask)
                return PTR_ERR(req);
 
        memset(&inarg, 0, sizeof(inarg));
-       inarg.mask = mask;
+       inarg.mask = mask & (MAY_READ | MAY_WRITE | MAY_EXEC);
        req->in.h.opcode = FUSE_ACCESS;
        req->in.h.nodeid = get_node_id(inode);
        req->in.numargs = 1;
@@ -927,7 +927,7 @@ static int fuse_access(struct inode *inode, int mask)
  * access request is sent.  Execute permission is still checked
  * locally based on file mode.
  */
-static int fuse_permission(struct inode *inode, int mask, struct nameidata *nd)
+static int fuse_permission(struct inode *inode, int mask)
 {
        struct fuse_conn *fc = get_fuse_conn(inode);
        bool refreshed = false;
@@ -962,7 +962,7 @@ static int fuse_permission(struct inode *inode, int mask, struct nameidata *nd)
                   exist.  So if permissions are revoked this won't be
                   noticed immediately, only after the attribute
                   timeout has expired */
-       } else if (nd && (nd->flags & (LOOKUP_ACCESS | LOOKUP_CHDIR))) {
+       } else if (mask & (MAY_ACCESS | MAY_CHDIR)) {
                err = fuse_access(inode, mask);
        } else if ((mask & MAY_EXEC) && S_ISREG(inode->i_mode)) {
                if (!(inode->i_mode & S_IXUGO)) {
index 1e252dfc52940c745dea61137afc386dbe183cd7..4e982532f085b6bf44fae8fdec89bb093b659852 100644 (file)
@@ -915,12 +915,6 @@ int gfs2_permission(struct inode *inode, int mask)
        return error;
 }
 
-static int gfs2_iop_permission(struct inode *inode, int mask,
-                              struct nameidata *nd)
-{
-       return gfs2_permission(inode, mask);
-}
-
 static int setattr_size(struct inode *inode, struct iattr *attr)
 {
        struct gfs2_inode *ip = GFS2_I(inode);
@@ -1150,7 +1144,7 @@ static int gfs2_removexattr(struct dentry *dentry, const char *name)
 }
 
 const struct inode_operations gfs2_file_iops = {
-       .permission = gfs2_iop_permission,
+       .permission = gfs2_permission,
        .setattr = gfs2_setattr,
        .getattr = gfs2_getattr,
        .setxattr = gfs2_setxattr,
@@ -1169,7 +1163,7 @@ const struct inode_operations gfs2_dir_iops = {
        .rmdir = gfs2_rmdir,
        .mknod = gfs2_mknod,
        .rename = gfs2_rename,
-       .permission = gfs2_iop_permission,
+       .permission = gfs2_permission,
        .setattr = gfs2_setattr,
        .getattr = gfs2_getattr,
        .setxattr = gfs2_setxattr,
@@ -1181,7 +1175,7 @@ const struct inode_operations gfs2_dir_iops = {
 const struct inode_operations gfs2_symlink_iops = {
        .readlink = gfs2_readlink,
        .follow_link = gfs2_follow_link,
-       .permission = gfs2_iop_permission,
+       .permission = gfs2_permission,
        .setattr = gfs2_setattr,
        .getattr = gfs2_getattr,
        .setxattr = gfs2_setxattr,
index dc4ec640e875974f0588ee60f3e478a4f0e4f7c6..aa73f3fd5dd90865283c1505e19ee9f1ffb0afe3 100644 (file)
@@ -511,8 +511,7 @@ void hfs_clear_inode(struct inode *inode)
        }
 }
 
-static int hfs_permission(struct inode *inode, int mask,
-                         struct nameidata *nd)
+static int hfs_permission(struct inode *inode, int mask)
 {
        if (S_ISREG(inode->i_mode) && mask & MAY_EXEC)
                return 0;
index cc3b5e24339b2089bf684cdafc7ebcee38ab928d..d4014e3044d2f729776cca3240c4cb4e3153f62a 100644 (file)
@@ -238,7 +238,7 @@ static void hfsplus_set_perms(struct inode *inode, struct hfsplus_perm *perms)
        perms->dev = cpu_to_be32(HFSPLUS_I(inode).dev);
 }
 
-static int hfsplus_permission(struct inode *inode, int mask, struct nameidata *nd)
+static int hfsplus_permission(struct inode *inode, int mask)
 {
        /* MAY_EXEC is also used for lookup, if no x bit is set allow lookup,
         * open_exec has the same test, so it's still not executable, if a x bit
index 5222345ddccf6525a13cd74fe801da1bde50a304..d6ecabf4d231f2a9aa9f1cf5b5e1c061ea28cf6c 100644 (file)
@@ -822,7 +822,7 @@ int hostfs_rename(struct inode *from_ino, struct dentry *from,
        return err;
 }
 
-int hostfs_permission(struct inode *ino, int desired, struct nameidata *nd)
+int hostfs_permission(struct inode *ino, int desired)
 {
        char *name;
        int r = 0, w = 0, x = 0, err;
index 4c80404a9abae4b61e075135bb62441450596b11..d98713777a1b62f2aa12f659dd872616d2dbeb4a 100644 (file)
@@ -314,7 +314,7 @@ static int jffs2_check_acl(struct inode *inode, int mask)
        return -EAGAIN;
 }
 
-int jffs2_permission(struct inode *inode, int mask, struct nameidata *nd)
+int jffs2_permission(struct inode *inode, int mask)
 {
        return generic_permission(inode, mask, jffs2_check_acl);
 }
index 0bb7f003fd80bb8b64909fedf420c3af327198c9..8ca058aed3840fa5f8c13c5b733127c473899739 100644 (file)
@@ -28,7 +28,7 @@ struct jffs2_acl_header {
 
 #define JFFS2_ACL_NOT_CACHED ((void *)-1)
 
-extern int jffs2_permission(struct inode *, int, struct nameidata *);
+extern int jffs2_permission(struct inode *, int);
 extern int jffs2_acl_chmod(struct inode *);
 extern int jffs2_init_acl_pre(struct inode *, struct inode *, int *);
 extern int jffs2_init_acl_post(struct inode *);
index 4d84bdc882999150a1e9bd7ae829f1aff24b33f2..d3e5c33665deceb13a0af0797a67b282129c3037 100644 (file)
@@ -140,7 +140,7 @@ static int jfs_check_acl(struct inode *inode, int mask)
        return -EAGAIN;
 }
 
-int jfs_permission(struct inode *inode, int mask, struct nameidata *nd)
+int jfs_permission(struct inode *inode, int mask)
 {
        return generic_permission(inode, mask, jfs_check_acl);
 }
index 455fa4292045559ea52202da59ae920dfe8d64ed..88475f10a3899dca4c6fa15eceffbbccb97cdab0 100644 (file)
@@ -20,7 +20,7 @@
 
 #ifdef CONFIG_JFS_POSIX_ACL
 
-int jfs_permission(struct inode *, int, struct nameidata *);
+int jfs_permission(struct inode *, int);
 int jfs_init_acl(tid_t, struct inode *, struct inode *);
 int jfs_setattr(struct dentry *, struct iattr *);
 
index 3b26a240ade94689cf4f8407dbd31d587185da9f..46af98ed136be9028a416ab8cb6c1d21954011d7 100644 (file)
@@ -185,6 +185,8 @@ int generic_permission(struct inode *inode, int mask,
 {
        umode_t                 mode = inode->i_mode;
 
+       mask &= MAY_READ | MAY_WRITE | MAY_EXEC;
+
        if (current->fsuid == inode->i_uid)
                mode >>= 6;
        else {
@@ -203,7 +205,7 @@ int generic_permission(struct inode *inode, int mask,
        /*
         * If the DACs are ok we don't need any capability check.
         */
-       if (((mode & mask & (MAY_READ|MAY_WRITE|MAY_EXEC)) == mask))
+       if ((mask & ~mode) == 0)
                return 0;
 
  check_capabilities:
@@ -228,7 +230,7 @@ int generic_permission(struct inode *inode, int mask,
 
 int permission(struct inode *inode, int mask, struct nameidata *nd)
 {
-       int retval, submask;
+       int retval;
        struct vfsmount *mnt = NULL;
 
        if (nd)
@@ -261,9 +263,17 @@ int permission(struct inode *inode, int mask, struct nameidata *nd)
        }
 
        /* Ordinary permission routines do not understand MAY_APPEND. */
-       submask = mask & ~MAY_APPEND;
        if (inode->i_op && inode->i_op->permission) {
-               retval = inode->i_op->permission(inode, submask, nd);
+               int extra = 0;
+               if (nd) {
+                       if (nd->flags & LOOKUP_ACCESS)
+                               extra |= MAY_ACCESS;
+                       if (nd->flags & LOOKUP_CHDIR)
+                               extra |= MAY_CHDIR;
+                       if (nd->flags & LOOKUP_OPEN)
+                               extra |= MAY_OPEN;
+               }
+               retval = inode->i_op->permission(inode, mask | extra);
                if (!retval) {
                        /*
                         * Exec permission on a regular file is denied if none
@@ -277,7 +287,7 @@ int permission(struct inode *inode, int mask, struct nameidata *nd)
                                return -EACCES;
                }
        } else {
-               retval = generic_permission(inode, submask, NULL);
+               retval = generic_permission(inode, mask, NULL);
        }
        if (retval)
                return retval;
@@ -286,7 +296,8 @@ int permission(struct inode *inode, int mask, struct nameidata *nd)
        if (retval)
                return retval;
 
-       return security_inode_permission(inode, mask, nd);
+       return security_inode_permission(inode,
+                       mask & (MAY_READ|MAY_WRITE|MAY_EXEC), nd);
 }
 
 /**
index 28a238dab23a2a16919ef58706a431447bcc8f5b..74f92b717f783ca1974094beabb879ea1adde0cc 100644 (file)
@@ -1884,7 +1884,7 @@ static int nfs_do_access(struct inode *inode, struct rpc_cred *cred, int mask)
                return status;
        nfs_access_add_cache(inode, &cache);
 out:
-       if ((cache.mask & mask) == mask)
+       if ((mask & ~cache.mask & (MAY_READ | MAY_WRITE | MAY_EXEC)) == 0)
                return 0;
        return -EACCES;
 }
@@ -1907,17 +1907,17 @@ int nfs_may_open(struct inode *inode, struct rpc_cred *cred, int openflags)
        return nfs_do_access(inode, cred, nfs_open_permission_mask(openflags));
 }
 
-int nfs_permission(struct inode *inode, int mask, struct nameidata *nd)
+int nfs_permission(struct inode *inode, int mask)
 {
        struct rpc_cred *cred;
        int res = 0;
 
        nfs_inc_stats(inode, NFSIOS_VFSACCESS);
 
-       if (mask == 0)
+       if ((mask & (MAY_READ | MAY_WRITE | MAY_EXEC)) == 0)
                goto out;
        /* Is this sys_access() ? */
-       if (nd != NULL && (nd->flags & LOOKUP_ACCESS))
+       if (mask & MAY_ACCESS)
                goto force_lookup;
 
        switch (inode->i_mode & S_IFMT) {
@@ -1926,8 +1926,7 @@ int nfs_permission(struct inode *inode, int mask, struct nameidata *nd)
                case S_IFREG:
                        /* NFSv4 has atomic_open... */
                        if (nfs_server_capable(inode, NFS_CAP_ATOMIC_OPEN)
-                                       && nd != NULL
-                                       && (nd->flags & LOOKUP_OPEN))
+                                       && (mask & MAY_OPEN))
                                goto out;
                        break;
                case S_IFDIR:
index e8514e8b6ce8977eb3f75d3a64a7b8f33f96726a..be2dd95d3a1dc0c916229ad4deb643ed0ee841b0 100644 (file)
@@ -1176,7 +1176,7 @@ bail:
        return err;
 }
 
-int ocfs2_permission(struct inode *inode, int mask, struct nameidata *nd)
+int ocfs2_permission(struct inode *inode, int mask)
 {
        int ret;
 
index 048ddcaf5c80e9b2bb76b1e06d3f6ddb340856c8..1e27b4d017ea49401ec43445a29d62bcd6b219ce 100644 (file)
@@ -62,8 +62,7 @@ int ocfs2_lock_allocators(struct inode *inode, struct ocfs2_dinode *di,
 int ocfs2_setattr(struct dentry *dentry, struct iattr *attr);
 int ocfs2_getattr(struct vfsmount *mnt, struct dentry *dentry,
                  struct kstat *stat);
-int ocfs2_permission(struct inode *inode, int mask,
-                    struct nameidata *nd);
+int ocfs2_permission(struct inode *inode, int mask);
 
 int ocfs2_should_update_atime(struct inode *inode,
                              struct vfsmount *vfsmnt);
index 81bce6791bfc3cccd000309c53cd328b6cfc7425..d82d800389f6018039abefa9668e7f7ad4f90c17 100644 (file)
@@ -1859,8 +1859,7 @@ static const struct file_operations proc_fd_operations = {
  * /proc/pid/fd needs a special permission handler so that a process can still
  * access /proc/self/fd after it has executed a setuid().
  */
-static int proc_fd_permission(struct inode *inode, int mask,
-                               struct nameidata *nd)
+static int proc_fd_permission(struct inode *inode, int mask)
 {
        int rv;
 
index fa1ec2433e44f33f795a0fc68e9c2b185e15e338..f9a8b892718fc2f1a04ce1d169ba1667378832b5 100644 (file)
@@ -292,7 +292,7 @@ out:
        return ret;
 }
 
-static int proc_sys_permission(struct inode *inode, int mask, struct nameidata *nd)
+static int proc_sys_permission(struct inode *inode, int mask)
 {
        /*
         * sysctl entries that are not writeable,
index d7c4935c1034b58d8a5399dcd22d63b2d645cc41..bb3cb5b7cdb2479d1b68b9eb2fa2521e54810490 100644 (file)
@@ -1250,7 +1250,7 @@ static int reiserfs_check_acl(struct inode *inode, int mask)
        return error;
 }
 
-int reiserfs_permission(struct inode *inode, int mask, struct nameidata *nd)
+int reiserfs_permission(struct inode *inode, int mask)
 {
        /*
         * We don't do permission checks on the internal objects.
index 2294783320cbd14a1b88cd2822122bed664e42cf..e4f8d51a5553651bd0235b2d4310ac9c44f32fb6 100644 (file)
@@ -408,7 +408,7 @@ smb_file_release(struct inode *inode, struct file * file)
  * privileges, so we need our own check for this.
  */
 static int
-smb_file_permission(struct inode *inode, int mask, struct nameidata *nd)
+smb_file_permission(struct inode *inode, int mask)
 {
        int mode = inode->i_mode;
        int error = 0;
@@ -417,7 +417,7 @@ smb_file_permission(struct inode *inode, int mask, struct nameidata *nd)
 
        /* Look at user permissions */
        mode >>= 6;
-       if ((mode & 7 & mask) != mask)
+       if (mask & ~mode & (MAY_READ | MAY_WRITE | MAY_EXEC))
                error = -EACCES;
        return error;
 }
index 2bf287ef54897af2651f24b39792404270179a19..5fc61c824bb9bbe1b53cca02ab6b72c427c900db 100644 (file)
@@ -589,8 +589,7 @@ xfs_check_acl(
 STATIC int
 xfs_vn_permission(
        struct inode            *inode,
-       int                     mask,
-       struct nameidata        *nd)
+       int                     mask)
 {
        return generic_permission(inode, mask, xfs_check_acl);
 }
index 31b75311e2ca381bc4d12fef44f577919a7e57a5..dcc228aa335ae43b77febde77dbecf4d031773b4 100644 (file)
@@ -37,7 +37,7 @@ extern const struct file_operations coda_ioctl_operations;
 /* operations shared over more than one file */
 int coda_open(struct inode *i, struct file *f);
 int coda_release(struct inode *i, struct file *f);
-int coda_permission(struct inode *inode, int mask, struct nameidata *nd);
+int coda_permission(struct inode *inode, int mask);
 int coda_revalidate_inode(struct dentry *);
 int coda_getattr(struct vfsmount *, struct dentry *, struct kstat *);
 int coda_setattr(struct dentry *, struct iattr *);
index 7721a2ac9c0e6b0a127a75c41835158e8ce36fd0..6c923c9b79bcdb6f5c4e1fa28287c4ca795130a8 100644 (file)
@@ -60,6 +60,9 @@ extern int dir_notify_enable;
 #define MAY_WRITE 2
 #define MAY_READ 4
 #define MAY_APPEND 8
+#define MAY_ACCESS 16
+#define MAY_CHDIR 32
+#define MAY_OPEN 64
 
 #define FMODE_READ 1
 #define FMODE_WRITE 2
@@ -1272,7 +1275,7 @@ struct inode_operations {
        void * (*follow_link) (struct dentry *, struct nameidata *);
        void (*put_link) (struct dentry *, struct nameidata *, void *);
        void (*truncate) (struct inode *);
-       int (*permission) (struct inode *, int, struct nameidata *);
+       int (*permission) (struct inode *, int);
        int (*setattr) (struct dentry *, struct iattr *);
        int (*getattr) (struct vfsmount *mnt, struct dentry *, struct kstat *);
        int (*setxattr) (struct dentry *, const char *,const void *,size_t,int);
index 29d26191873428cecde2b29f3fd68b855684f614..f08f9ca602afef18a20850742f13a37266c007ea 100644 (file)
@@ -332,7 +332,7 @@ extern int nfs_refresh_inode(struct inode *, struct nfs_fattr *);
 extern int nfs_post_op_update_inode(struct inode *inode, struct nfs_fattr *fattr);
 extern int nfs_post_op_update_inode_force_wcc(struct inode *inode, struct nfs_fattr *fattr);
 extern int nfs_getattr(struct vfsmount *, struct dentry *, struct kstat *);
-extern int nfs_permission(struct inode *, int, struct nameidata *);
+extern int nfs_permission(struct inode *, int);
 extern int nfs_open(struct inode *, struct file *);
 extern int nfs_release(struct inode *, struct file *);
 extern int nfs_attribute_timeout(struct inode *inode);
index 66a96814d614c7dd23c4371d80a54a1a829b6a84..af135ae895db2d3523839c5f1a0857ed54db3aca 100644 (file)
@@ -55,7 +55,7 @@ int reiserfs_removexattr(struct dentry *dentry, const char *name);
 int reiserfs_delete_xattrs(struct inode *inode);
 int reiserfs_chown_xattrs(struct inode *inode, struct iattr *attrs);
 int reiserfs_xattr_init(struct super_block *sb, int mount_flags);
-int reiserfs_permission(struct inode *inode, int mask, struct nameidata *nd);
+int reiserfs_permission(struct inode *inode, int mask);
 
 int reiserfs_xattr_del(struct inode *, const char *);
 int reiserfs_xattr_get(const struct inode *, const char *, void *, size_t);
index f2d12d5a21b891cf53cbe19da6d10ded434aab59..fd83f2584b157b5e76b593344c55f3381f149014 100644 (file)
@@ -43,7 +43,7 @@ static inline struct shmem_inode_info *SHMEM_I(struct inode *inode)
 }
 
 #ifdef CONFIG_TMPFS_POSIX_ACL
-int shmem_permission(struct inode *, int, struct nameidata *);
+int shmem_permission(struct inode *, int);
 int shmem_acl_init(struct inode *, struct inode *);
 void shmem_acl_destroy_inode(struct inode *);
 
index ff5abcca5ddfb3412b8016500002e7921c2404ba..911d846f0503697b2fbb8c01ff95a78d2d37e4b3 100644 (file)
@@ -1516,9 +1516,9 @@ static int do_sysctl_strategy(struct ctl_table_root *root,
        int op = 0, rc;
 
        if (oldval)
-               op |= 004;
+               op |= MAY_READ;
        if (newval)
-               op |= 002;
+               op |= MAY_WRITE;
        if (sysctl_perm(root, table, op))
                return -EPERM;
 
@@ -1560,7 +1560,7 @@ repeat:
                if (n == table->ctl_name) {
                        int error;
                        if (table->child) {
-                               if (sysctl_perm(root, table, 001))
+                               if (sysctl_perm(root, table, MAY_EXEC))
                                        return -EPERM;
                                name++;
                                nlen--;
@@ -1635,7 +1635,7 @@ static int test_perm(int mode, int op)
                mode >>= 6;
        else if (in_egroup_p(0))
                mode >>= 3;
-       if ((mode & op & 0007) == op)
+       if ((op & ~mode & (MAY_READ|MAY_WRITE|MAY_EXEC)) == 0)
                return 0;
        return -EACCES;
 }
@@ -1645,7 +1645,7 @@ int sysctl_perm(struct ctl_table_root *root, struct ctl_table *table, int op)
        int error;
        int mode;
 
-       error = security_sysctl(table, op);
+       error = security_sysctl(table, op & (MAY_READ | MAY_WRITE | MAY_EXEC));
        if (error)
                return error;
 
index f5664c5b9eb1433425501486562c3c6bb98b2237..8e5aadd7dcd6aef09f581d3ff925072cc494b0c0 100644 (file)
@@ -191,7 +191,7 @@ shmem_check_acl(struct inode *inode, int mask)
  * shmem_permission  -  permission() inode operation
  */
 int
-shmem_permission(struct inode *inode, int mask, struct nameidata *nd)
+shmem_permission(struct inode *inode, int mask)
 {
        return generic_permission(inode, mask, shmem_check_acl);
 }