diff options
| author | Al Viro <viro@zeniv.linux.org.uk> | 2008-07-15 21:03:57 -0400 |
|---|---|---|
| committer | Al Viro <viro@zeniv.linux.org.uk> | 2008-07-26 20:53:14 -0400 |
| commit | e6305c43eda10ebfd2ad9e35d6e172ccc7bb3695 (patch) | |
| tree | 8a95bd0e27fb3ce895cca9ef91af2e1605e4cdab | |
| parent | 1bd5191d9f5d1928c4efdf604c4164b04bb88dbe (diff) | |
[PATCH] sanitize ->permission() prototype
* 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, 74 insertions, 87 deletions
diff --git a/fs/afs/internal.h b/fs/afs/internal.h index 7102824ba847..3cb6920ff30b 100644 --- a/fs/afs/internal.h +++ b/fs/afs/internal.h | |||
| @@ -469,8 +469,6 @@ extern bool afs_cm_incoming_call(struct afs_call *); | |||
| 469 | extern const struct inode_operations afs_dir_inode_operations; | 469 | extern const struct inode_operations afs_dir_inode_operations; |
| 470 | extern const struct file_operations afs_dir_file_operations; | 470 | extern const struct file_operations afs_dir_file_operations; |
| 471 | 471 | ||
| 472 | extern int afs_permission(struct inode *, int, struct nameidata *); | ||
| 473 | |||
| 474 | /* | 472 | /* |
| 475 | * file.c | 473 | * file.c |
| 476 | */ | 474 | */ |
| @@ -605,7 +603,7 @@ extern void afs_clear_permits(struct afs_vnode *); | |||
| 605 | extern void afs_cache_permit(struct afs_vnode *, struct key *, long); | 603 | extern void afs_cache_permit(struct afs_vnode *, struct key *, long); |
| 606 | extern void afs_zap_permits(struct rcu_head *); | 604 | extern void afs_zap_permits(struct rcu_head *); |
| 607 | extern struct key *afs_request_key(struct afs_cell *); | 605 | extern struct key *afs_request_key(struct afs_cell *); |
| 608 | extern int afs_permission(struct inode *, int, struct nameidata *); | 606 | extern int afs_permission(struct inode *, int); |
| 609 | 607 | ||
| 610 | /* | 608 | /* |
| 611 | * server.c | 609 | * server.c |
diff --git a/fs/afs/security.c b/fs/afs/security.c index 3bcbeceba1bb..3ef504370034 100644 --- a/fs/afs/security.c +++ b/fs/afs/security.c | |||
| @@ -284,7 +284,7 @@ static int afs_check_permit(struct afs_vnode *vnode, struct key *key, | |||
| 284 | * - AFS ACLs are attached to directories only, and a file is controlled by its | 284 | * - AFS ACLs are attached to directories only, and a file is controlled by its |
| 285 | * parent directory's ACL | 285 | * parent directory's ACL |
| 286 | */ | 286 | */ |
| 287 | int afs_permission(struct inode *inode, int mask, struct nameidata *nd) | 287 | int afs_permission(struct inode *inode, int mask) |
| 288 | { | 288 | { |
| 289 | struct afs_vnode *vnode = AFS_FS_I(inode); | 289 | struct afs_vnode *vnode = AFS_FS_I(inode); |
| 290 | afs_access_t uninitialized_var(access); | 290 | afs_access_t uninitialized_var(access); |
diff --git a/fs/bad_inode.c b/fs/bad_inode.c index f1c2ea8342f5..5f1538c03b1b 100644 --- a/fs/bad_inode.c +++ b/fs/bad_inode.c | |||
| @@ -243,8 +243,7 @@ static int bad_inode_readlink(struct dentry *dentry, char __user *buffer, | |||
| 243 | return -EIO; | 243 | return -EIO; |
| 244 | } | 244 | } |
| 245 | 245 | ||
| 246 | static int bad_inode_permission(struct inode *inode, int mask, | 246 | static int bad_inode_permission(struct inode *inode, int mask) |
| 247 | struct nameidata *nd) | ||
| 248 | { | 247 | { |
| 249 | return -EIO; | 248 | return -EIO; |
| 250 | } | 249 | } |
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index fe5f6809cba6..1ec7076f7b24 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c | |||
| @@ -267,7 +267,7 @@ cifs_statfs(struct dentry *dentry, struct kstatfs *buf) | |||
| 267 | return 0; | 267 | return 0; |
| 268 | } | 268 | } |
| 269 | 269 | ||
| 270 | static int cifs_permission(struct inode *inode, int mask, struct nameidata *nd) | 270 | static int cifs_permission(struct inode *inode, int mask) |
| 271 | { | 271 | { |
| 272 | struct cifs_sb_info *cifs_sb; | 272 | struct cifs_sb_info *cifs_sb; |
| 273 | 273 | ||
diff --git a/fs/coda/dir.c b/fs/coda/dir.c index 3d2580e00a3e..c5916228243c 100644 --- a/fs/coda/dir.c +++ b/fs/coda/dir.c | |||
| @@ -137,9 +137,11 @@ exit: | |||
| 137 | } | 137 | } |
| 138 | 138 | ||
| 139 | 139 | ||
| 140 | int coda_permission(struct inode *inode, int mask, struct nameidata *nd) | 140 | int coda_permission(struct inode *inode, int mask) |
| 141 | { | 141 | { |
| 142 | int error = 0; | 142 | int error = 0; |
| 143 | |||
| 144 | mask &= MAY_READ | MAY_WRITE | MAY_EXEC; | ||
| 143 | 145 | ||
| 144 | if (!mask) | 146 | if (!mask) |
| 145 | return 0; | 147 | return 0; |
diff --git a/fs/coda/pioctl.c b/fs/coda/pioctl.c index c21a1f552a63..c38a98974fb0 100644 --- a/fs/coda/pioctl.c +++ b/fs/coda/pioctl.c | |||
| @@ -24,8 +24,7 @@ | |||
| 24 | #include <linux/coda_psdev.h> | 24 | #include <linux/coda_psdev.h> |
| 25 | 25 | ||
| 26 | /* pioctl ops */ | 26 | /* pioctl ops */ |
| 27 | static int coda_ioctl_permission(struct inode *inode, int mask, | 27 | static int coda_ioctl_permission(struct inode *inode, int mask); |
| 28 | struct nameidata *nd); | ||
| 29 | static int coda_pioctl(struct inode * inode, struct file * filp, | 28 | static int coda_pioctl(struct inode * inode, struct file * filp, |
| 30 | unsigned int cmd, unsigned long user_data); | 29 | unsigned int cmd, unsigned long user_data); |
| 31 | 30 | ||
| @@ -42,8 +41,7 @@ const struct file_operations coda_ioctl_operations = { | |||
| 42 | }; | 41 | }; |
| 43 | 42 | ||
| 44 | /* the coda pioctl inode ops */ | 43 | /* the coda pioctl inode ops */ |
| 45 | static int coda_ioctl_permission(struct inode *inode, int mask, | 44 | static int coda_ioctl_permission(struct inode *inode, int mask) |
| 46 | struct nameidata *nd) | ||
| 47 | { | 45 | { |
| 48 | return 0; | 46 | return 0; |
| 49 | } | 47 | } |
diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c index d755455e3bff..32f4228efcd5 100644 --- a/fs/ecryptfs/inode.c +++ b/fs/ecryptfs/inode.c | |||
| @@ -830,22 +830,9 @@ out: | |||
| 830 | } | 830 | } |
| 831 | 831 | ||
| 832 | static int | 832 | static int |
| 833 | ecryptfs_permission(struct inode *inode, int mask, struct nameidata *nd) | 833 | ecryptfs_permission(struct inode *inode, int mask) |
| 834 | { | 834 | { |
| 835 | int rc; | 835 | return permission(ecryptfs_inode_to_lower(inode), mask, NULL); |
| 836 | |||
| 837 | if (nd) { | ||
| 838 | struct vfsmount *vfsmnt_save = nd->path.mnt; | ||
| 839 | struct dentry *dentry_save = nd->path.dentry; | ||
| 840 | |||
| 841 | nd->path.mnt = ecryptfs_dentry_to_lower_mnt(nd->path.dentry); | ||
| 842 | nd->path.dentry = ecryptfs_dentry_to_lower(nd->path.dentry); | ||
| 843 | rc = permission(ecryptfs_inode_to_lower(inode), mask, nd); | ||
| 844 | nd->path.mnt = vfsmnt_save; | ||
| 845 | nd->path.dentry = dentry_save; | ||
| 846 | } else | ||
| 847 | rc = permission(ecryptfs_inode_to_lower(inode), mask, NULL); | ||
| 848 | return rc; | ||
| 849 | } | 836 | } |
| 850 | 837 | ||
| 851 | /** | 838 | /** |
diff --git a/fs/ext2/acl.c b/fs/ext2/acl.c index e58669e1b87c..ae8c4f850b27 100644 --- a/fs/ext2/acl.c +++ b/fs/ext2/acl.c | |||
| @@ -294,7 +294,7 @@ ext2_check_acl(struct inode *inode, int mask) | |||
| 294 | } | 294 | } |
| 295 | 295 | ||
| 296 | int | 296 | int |
| 297 | ext2_permission(struct inode *inode, int mask, struct nameidata *nd) | 297 | ext2_permission(struct inode *inode, int mask) |
| 298 | { | 298 | { |
| 299 | return generic_permission(inode, mask, ext2_check_acl); | 299 | return generic_permission(inode, mask, ext2_check_acl); |
| 300 | } | 300 | } |
diff --git a/fs/ext2/acl.h b/fs/ext2/acl.h index 0bde85bafe38..b42cf578554b 100644 --- a/fs/ext2/acl.h +++ b/fs/ext2/acl.h | |||
| @@ -58,7 +58,7 @@ static inline int ext2_acl_count(size_t size) | |||
| 58 | #define EXT2_ACL_NOT_CACHED ((void *)-1) | 58 | #define EXT2_ACL_NOT_CACHED ((void *)-1) |
| 59 | 59 | ||
| 60 | /* acl.c */ | 60 | /* acl.c */ |
| 61 | extern int ext2_permission (struct inode *, int, struct nameidata *); | 61 | extern int ext2_permission (struct inode *, int); |
| 62 | extern int ext2_acl_chmod (struct inode *); | 62 | extern int ext2_acl_chmod (struct inode *); |
| 63 | extern int ext2_init_acl (struct inode *, struct inode *); | 63 | extern int ext2_init_acl (struct inode *, struct inode *); |
| 64 | 64 | ||
diff --git a/fs/ext3/acl.c b/fs/ext3/acl.c index a754d1848173..b60bb241880c 100644 --- a/fs/ext3/acl.c +++ b/fs/ext3/acl.c | |||
| @@ -299,7 +299,7 @@ ext3_check_acl(struct inode *inode, int mask) | |||
| 299 | } | 299 | } |
| 300 | 300 | ||
| 301 | int | 301 | int |
| 302 | ext3_permission(struct inode *inode, int mask, struct nameidata *nd) | 302 | ext3_permission(struct inode *inode, int mask) |
| 303 | { | 303 | { |
| 304 | return generic_permission(inode, mask, ext3_check_acl); | 304 | return generic_permission(inode, mask, ext3_check_acl); |
| 305 | } | 305 | } |
diff --git a/fs/ext3/acl.h b/fs/ext3/acl.h index 0d1e6279cbfd..42da16b8cac0 100644 --- a/fs/ext3/acl.h +++ b/fs/ext3/acl.h | |||
| @@ -58,7 +58,7 @@ static inline int ext3_acl_count(size_t size) | |||
| 58 | #define EXT3_ACL_NOT_CACHED ((void *)-1) | 58 | #define EXT3_ACL_NOT_CACHED ((void *)-1) |
| 59 | 59 | ||
| 60 | /* acl.c */ | 60 | /* acl.c */ |
| 61 | extern int ext3_permission (struct inode *, int, struct nameidata *); | 61 | extern int ext3_permission (struct inode *, int); |
| 62 | extern int ext3_acl_chmod (struct inode *); | 62 | extern int ext3_acl_chmod (struct inode *); |
| 63 | extern int ext3_init_acl (handle_t *, struct inode *, struct inode *); | 63 | extern int ext3_init_acl (handle_t *, struct inode *, struct inode *); |
| 64 | 64 | ||
diff --git a/fs/ext4/acl.c b/fs/ext4/acl.c index 3c8dab880d91..c7d04e165446 100644 --- a/fs/ext4/acl.c +++ b/fs/ext4/acl.c | |||
| @@ -299,7 +299,7 @@ ext4_check_acl(struct inode *inode, int mask) | |||
| 299 | } | 299 | } |
| 300 | 300 | ||
| 301 | int | 301 | int |
| 302 | ext4_permission(struct inode *inode, int mask, struct nameidata *nd) | 302 | ext4_permission(struct inode *inode, int mask) |
| 303 | { | 303 | { |
| 304 | return generic_permission(inode, mask, ext4_check_acl); | 304 | return generic_permission(inode, mask, ext4_check_acl); |
| 305 | } | 305 | } |
diff --git a/fs/ext4/acl.h b/fs/ext4/acl.h index 26a5c1abf147..cd2b855a07d6 100644 --- a/fs/ext4/acl.h +++ b/fs/ext4/acl.h | |||
| @@ -58,7 +58,7 @@ static inline int ext4_acl_count(size_t size) | |||
| 58 | #define EXT4_ACL_NOT_CACHED ((void *)-1) | 58 | #define EXT4_ACL_NOT_CACHED ((void *)-1) |
| 59 | 59 | ||
| 60 | /* acl.c */ | 60 | /* acl.c */ |
| 61 | extern int ext4_permission (struct inode *, int, struct nameidata *); | 61 | extern int ext4_permission (struct inode *, int); |
| 62 | extern int ext4_acl_chmod (struct inode *); | 62 | extern int ext4_acl_chmod (struct inode *); |
| 63 | extern int ext4_init_acl (handle_t *, struct inode *, struct inode *); | 63 | extern int ext4_init_acl (handle_t *, struct inode *, struct inode *); |
| 64 | 64 | ||
diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c index 51d0035ff07e..48a7934cb950 100644 --- a/fs/fuse/dir.c +++ b/fs/fuse/dir.c | |||
| @@ -898,7 +898,7 @@ static int fuse_access(struct inode *inode, int mask) | |||
| 898 | return PTR_ERR(req); | 898 | return PTR_ERR(req); |
| 899 | 899 | ||
| 900 | memset(&inarg, 0, sizeof(inarg)); | 900 | memset(&inarg, 0, sizeof(inarg)); |
| 901 | inarg.mask = mask; | 901 | inarg.mask = mask & (MAY_READ | MAY_WRITE | MAY_EXEC); |
| 902 | req->in.h.opcode = FUSE_ACCESS; | 902 | req->in.h.opcode = FUSE_ACCESS; |
| 903 | req->in.h.nodeid = get_node_id(inode); | 903 | req->in.h.nodeid = get_node_id(inode); |
| 904 | req->in.numargs = 1; | 904 | req->in.numargs = 1; |
| @@ -927,7 +927,7 @@ static int fuse_access(struct inode *inode, int mask) | |||
| 927 | * access request is sent. Execute permission is still checked | 927 | * access request is sent. Execute permission is still checked |
| 928 | * locally based on file mode. | 928 | * locally based on file mode. |
| 929 | */ | 929 | */ |
| 930 | static int fuse_permission(struct inode *inode, int mask, struct nameidata *nd) | 930 | static int fuse_permission(struct inode *inode, int mask) |
| 931 | { | 931 | { |
| 932 | struct fuse_conn *fc = get_fuse_conn(inode); | 932 | struct fuse_conn *fc = get_fuse_conn(inode); |
| 933 | bool refreshed = false; | 933 | bool refreshed = false; |
| @@ -962,7 +962,7 @@ static int fuse_permission(struct inode *inode, int mask, struct nameidata *nd) | |||
| 962 | exist. So if permissions are revoked this won't be | 962 | exist. So if permissions are revoked this won't be |
| 963 | noticed immediately, only after the attribute | 963 | noticed immediately, only after the attribute |
| 964 | timeout has expired */ | 964 | timeout has expired */ |
| 965 | } else if (nd && (nd->flags & (LOOKUP_ACCESS | LOOKUP_CHDIR))) { | 965 | } else if (mask & (MAY_ACCESS | MAY_CHDIR)) { |
| 966 | err = fuse_access(inode, mask); | 966 | err = fuse_access(inode, mask); |
| 967 | } else if ((mask & MAY_EXEC) && S_ISREG(inode->i_mode)) { | 967 | } else if ((mask & MAY_EXEC) && S_ISREG(inode->i_mode)) { |
| 968 | if (!(inode->i_mode & S_IXUGO)) { | 968 | if (!(inode->i_mode & S_IXUGO)) { |
diff --git a/fs/gfs2/ops_inode.c b/fs/gfs2/ops_inode.c index 1e252dfc5294..4e982532f085 100644 --- a/fs/gfs2/ops_inode.c +++ b/fs/gfs2/ops_inode.c | |||
| @@ -915,12 +915,6 @@ int gfs2_permission(struct inode *inode, int mask) | |||
| 915 | return error; | 915 | return error; |
| 916 | } | 916 | } |
| 917 | 917 | ||
| 918 | static int gfs2_iop_permission(struct inode *inode, int mask, | ||
| 919 | struct nameidata *nd) | ||
| 920 | { | ||
| 921 | return gfs2_permission(inode, mask); | ||
| 922 | } | ||
| 923 | |||
| 924 | static int setattr_size(struct inode *inode, struct iattr *attr) | 918 | static int setattr_size(struct inode *inode, struct iattr *attr) |
| 925 | { | 919 | { |
| 926 | struct gfs2_inode *ip = GFS2_I(inode); | 920 | struct gfs2_inode *ip = GFS2_I(inode); |
| @@ -1150,7 +1144,7 @@ static int gfs2_removexattr(struct dentry *dentry, const char *name) | |||
| 1150 | } | 1144 | } |
| 1151 | 1145 | ||
| 1152 | const struct inode_operations gfs2_file_iops = { | 1146 | const struct inode_operations gfs2_file_iops = { |
| 1153 | .permission = gfs2_iop_permission, | 1147 | .permission = gfs2_permission, |
| 1154 | .setattr = gfs2_setattr, | 1148 | .setattr = gfs2_setattr, |
| 1155 | .getattr = gfs2_getattr, | 1149 | .getattr = gfs2_getattr, |
| 1156 | .setxattr = gfs2_setxattr, | 1150 | .setxattr = gfs2_setxattr, |
| @@ -1169,7 +1163,7 @@ const struct inode_operations gfs2_dir_iops = { | |||
| 1169 | .rmdir = gfs2_rmdir, | 1163 | .rmdir = gfs2_rmdir, |
| 1170 | .mknod = gfs2_mknod, | 1164 | .mknod = gfs2_mknod, |
| 1171 | .rename = gfs2_rename, | 1165 | .rename = gfs2_rename, |
| 1172 | .permission = gfs2_iop_permission, | 1166 | .permission = gfs2_permission, |
| 1173 | .setattr = gfs2_setattr, | 1167 | .setattr = gfs2_setattr, |
| 1174 | .getattr = gfs2_getattr, | 1168 | .getattr = gfs2_getattr, |
| 1175 | .setxattr = gfs2_setxattr, | 1169 | .setxattr = gfs2_setxattr, |
| @@ -1181,7 +1175,7 @@ const struct inode_operations gfs2_dir_iops = { | |||
| 1181 | const struct inode_operations gfs2_symlink_iops = { | 1175 | const struct inode_operations gfs2_symlink_iops = { |
| 1182 | .readlink = gfs2_readlink, | 1176 | .readlink = gfs2_readlink, |
| 1183 | .follow_link = gfs2_follow_link, | 1177 | .follow_link = gfs2_follow_link, |
| 1184 | .permission = gfs2_iop_permission, | 1178 | .permission = gfs2_permission, |
| 1185 | .setattr = gfs2_setattr, | 1179 | .setattr = gfs2_setattr, |
| 1186 | .getattr = gfs2_getattr, | 1180 | .getattr = gfs2_getattr, |
| 1187 | .setxattr = gfs2_setxattr, | 1181 | .setxattr = gfs2_setxattr, |
diff --git a/fs/hfs/inode.c b/fs/hfs/inode.c index dc4ec640e875..aa73f3fd5dd9 100644 --- a/fs/hfs/inode.c +++ b/fs/hfs/inode.c | |||
| @@ -511,8 +511,7 @@ void hfs_clear_inode(struct inode *inode) | |||
| 511 | } | 511 | } |
| 512 | } | 512 | } |
| 513 | 513 | ||
| 514 | static int hfs_permission(struct inode *inode, int mask, | 514 | static int hfs_permission(struct inode *inode, int mask) |
| 515 | struct nameidata *nd) | ||
| 516 | { | 515 | { |
| 517 | if (S_ISREG(inode->i_mode) && mask & MAY_EXEC) | 516 | if (S_ISREG(inode->i_mode) && mask & MAY_EXEC) |
| 518 | return 0; | 517 | return 0; |
diff --git a/fs/hfsplus/inode.c b/fs/hfsplus/inode.c index cc3b5e24339b..d4014e3044d2 100644 --- a/fs/hfsplus/inode.c +++ b/fs/hfsplus/inode.c | |||
| @@ -238,7 +238,7 @@ static void hfsplus_set_perms(struct inode *inode, struct hfsplus_perm *perms) | |||
| 238 | perms->dev = cpu_to_be32(HFSPLUS_I(inode).dev); | 238 | perms->dev = cpu_to_be32(HFSPLUS_I(inode).dev); |
| 239 | } | 239 | } |
| 240 | 240 | ||
| 241 | static int hfsplus_permission(struct inode *inode, int mask, struct nameidata *nd) | 241 | static int hfsplus_permission(struct inode *inode, int mask) |
| 242 | { | 242 | { |
| 243 | /* MAY_EXEC is also used for lookup, if no x bit is set allow lookup, | 243 | /* MAY_EXEC is also used for lookup, if no x bit is set allow lookup, |
| 244 | * open_exec has the same test, so it's still not executable, if a x bit | 244 | * open_exec has the same test, so it's still not executable, if a x bit |
diff --git a/fs/hostfs/hostfs_kern.c b/fs/hostfs/hostfs_kern.c index 5222345ddccf..d6ecabf4d231 100644 --- a/fs/hostfs/hostfs_kern.c +++ b/fs/hostfs/hostfs_kern.c | |||
| @@ -822,7 +822,7 @@ int hostfs_rename(struct inode *from_ino, struct dentry *from, | |||
| 822 | return err; | 822 | return err; |
| 823 | } | 823 | } |
| 824 | 824 | ||
| 825 | int hostfs_permission(struct inode *ino, int desired, struct nameidata *nd) | 825 | int hostfs_permission(struct inode *ino, int desired) |
| 826 | { | 826 | { |
| 827 | char *name; | 827 | char *name; |
| 828 | int r = 0, w = 0, x = 0, err; | 828 | int r = 0, w = 0, x = 0, err; |
diff --git a/fs/jffs2/acl.c b/fs/jffs2/acl.c index 4c80404a9aba..d98713777a1b 100644 --- a/fs/jffs2/acl.c +++ b/fs/jffs2/acl.c | |||
| @@ -314,7 +314,7 @@ static int jffs2_check_acl(struct inode *inode, int mask) | |||
| 314 | return -EAGAIN; | 314 | return -EAGAIN; |
| 315 | } | 315 | } |
| 316 | 316 | ||
| 317 | int jffs2_permission(struct inode *inode, int mask, struct nameidata *nd) | 317 | int jffs2_permission(struct inode *inode, int mask) |
| 318 | { | 318 | { |
| 319 | return generic_permission(inode, mask, jffs2_check_acl); | 319 | return generic_permission(inode, mask, jffs2_check_acl); |
| 320 | } | 320 | } |
diff --git a/fs/jffs2/acl.h b/fs/jffs2/acl.h index 0bb7f003fd80..8ca058aed384 100644 --- a/fs/jffs2/acl.h +++ b/fs/jffs2/acl.h | |||
| @@ -28,7 +28,7 @@ struct jffs2_acl_header { | |||
| 28 | 28 | ||
| 29 | #define JFFS2_ACL_NOT_CACHED ((void *)-1) | 29 | #define JFFS2_ACL_NOT_CACHED ((void *)-1) |
| 30 | 30 | ||
| 31 | extern int jffs2_permission(struct inode *, int, struct nameidata *); | 31 | extern int jffs2_permission(struct inode *, int); |
| 32 | extern int jffs2_acl_chmod(struct inode *); | 32 | extern int jffs2_acl_chmod(struct inode *); |
| 33 | extern int jffs2_init_acl_pre(struct inode *, struct inode *, int *); | 33 | extern int jffs2_init_acl_pre(struct inode *, struct inode *, int *); |
| 34 | extern int jffs2_init_acl_post(struct inode *); | 34 | extern int jffs2_init_acl_post(struct inode *); |
diff --git a/fs/jfs/acl.c b/fs/jfs/acl.c index 4d84bdc88299..d3e5c33665de 100644 --- a/fs/jfs/acl.c +++ b/fs/jfs/acl.c | |||
| @@ -140,7 +140,7 @@ static int jfs_check_acl(struct inode *inode, int mask) | |||
| 140 | return -EAGAIN; | 140 | return -EAGAIN; |
| 141 | } | 141 | } |
| 142 | 142 | ||
| 143 | int jfs_permission(struct inode *inode, int mask, struct nameidata *nd) | 143 | int jfs_permission(struct inode *inode, int mask) |
| 144 | { | 144 | { |
| 145 | return generic_permission(inode, mask, jfs_check_acl); | 145 | return generic_permission(inode, mask, jfs_check_acl); |
| 146 | } | 146 | } |
diff --git a/fs/jfs/jfs_acl.h b/fs/jfs/jfs_acl.h index 455fa4292045..88475f10a389 100644 --- a/fs/jfs/jfs_acl.h +++ b/fs/jfs/jfs_acl.h | |||
| @@ -20,7 +20,7 @@ | |||
| 20 | 20 | ||
| 21 | #ifdef CONFIG_JFS_POSIX_ACL | 21 | #ifdef CONFIG_JFS_POSIX_ACL |
| 22 | 22 | ||
| 23 | int jfs_permission(struct inode *, int, struct nameidata *); | 23 | int jfs_permission(struct inode *, int); |
| 24 | int jfs_init_acl(tid_t, struct inode *, struct inode *); | 24 | int jfs_init_acl(tid_t, struct inode *, struct inode *); |
| 25 | int jfs_setattr(struct dentry *, struct iattr *); | 25 | int jfs_setattr(struct dentry *, struct iattr *); |
| 26 | 26 | ||
diff --git a/fs/namei.c b/fs/namei.c index 3b26a240ade9..46af98ed136b 100644 --- a/fs/namei.c +++ b/fs/namei.c | |||
| @@ -185,6 +185,8 @@ int generic_permission(struct inode *inode, int mask, | |||
| 185 | { | 185 | { |
| 186 | umode_t mode = inode->i_mode; | 186 | umode_t mode = inode->i_mode; |
| 187 | 187 | ||
| 188 | mask &= MAY_READ | MAY_WRITE | MAY_EXEC; | ||
| 189 | |||
| 188 | if (current->fsuid == inode->i_uid) | 190 | if (current->fsuid == inode->i_uid) |
| 189 | mode >>= 6; | 191 | mode >>= 6; |
| 190 | else { | 192 | else { |
| @@ -203,7 +205,7 @@ int generic_permission(struct inode *inode, int mask, | |||
| 203 | /* | 205 | /* |
| 204 | * If the DACs are ok we don't need any capability check. | 206 | * If the DACs are ok we don't need any capability check. |
| 205 | */ | 207 | */ |
| 206 | if (((mode & mask & (MAY_READ|MAY_WRITE|MAY_EXEC)) == mask)) | 208 | if ((mask & ~mode) == 0) |
| 207 | return 0; | 209 | return 0; |
| 208 | 210 | ||
| 209 | check_capabilities: | 211 | check_capabilities: |
| @@ -228,7 +230,7 @@ int generic_permission(struct inode *inode, int mask, | |||
| 228 | 230 | ||
| 229 | int permission(struct inode *inode, int mask, struct nameidata *nd) | 231 | int permission(struct inode *inode, int mask, struct nameidata *nd) |
| 230 | { | 232 | { |
| 231 | int retval, submask; | 233 | int retval; |
| 232 | struct vfsmount *mnt = NULL; | 234 | struct vfsmount *mnt = NULL; |
| 233 | 235 | ||
| 234 | if (nd) | 236 | if (nd) |
| @@ -261,9 +263,17 @@ int permission(struct inode *inode, int mask, struct nameidata *nd) | |||
| 261 | } | 263 | } |
| 262 | 264 | ||
| 263 | /* Ordinary permission routines do not understand MAY_APPEND. */ | 265 | /* Ordinary permission routines do not understand MAY_APPEND. */ |
| 264 | submask = mask & ~MAY_APPEND; | ||
| 265 | if (inode->i_op && inode->i_op->permission) { | 266 | if (inode->i_op && inode->i_op->permission) { |
| 266 | retval = inode->i_op->permission(inode, submask, nd); | 267 | int extra = 0; |
| 268 | if (nd) { | ||
| 269 | if (nd->flags & LOOKUP_ACCESS) | ||
| 270 | extra |= MAY_ACCESS; | ||
| 271 | if (nd->flags & LOOKUP_CHDIR) | ||
| 272 | extra |= MAY_CHDIR; | ||
| 273 | if (nd->flags & LOOKUP_OPEN) | ||
| 274 | extra |= MAY_OPEN; | ||
| 275 | } | ||
| 276 | retval = inode->i_op->permission(inode, mask | extra); | ||
| 267 | if (!retval) { | 277 | if (!retval) { |
| 268 | /* | 278 | /* |
| 269 | * Exec permission on a regular file is denied if none | 279 | * Exec permission on a regular file is denied if none |
| @@ -277,7 +287,7 @@ int permission(struct inode *inode, int mask, struct nameidata *nd) | |||
| 277 | return -EACCES; | 287 | return -EACCES; |
| 278 | } | 288 | } |
| 279 | } else { | 289 | } else { |
| 280 | retval = generic_permission(inode, submask, NULL); | 290 | retval = generic_permission(inode, mask, NULL); |
| 281 | } | 291 | } |
| 282 | if (retval) | 292 | if (retval) |
| 283 | return retval; | 293 | return retval; |
| @@ -286,7 +296,8 @@ int permission(struct inode *inode, int mask, struct nameidata *nd) | |||
| 286 | if (retval) | 296 | if (retval) |
| 287 | return retval; | 297 | return retval; |
| 288 | 298 | ||
| 289 | return security_inode_permission(inode, mask, nd); | 299 | return security_inode_permission(inode, |
| 300 | mask & (MAY_READ|MAY_WRITE|MAY_EXEC), nd); | ||
| 290 | } | 301 | } |
| 291 | 302 | ||
| 292 | /** | 303 | /** |
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index 28a238dab23a..74f92b717f78 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c | |||
| @@ -1884,7 +1884,7 @@ static int nfs_do_access(struct inode *inode, struct rpc_cred *cred, int mask) | |||
| 1884 | return status; | 1884 | return status; |
| 1885 | nfs_access_add_cache(inode, &cache); | 1885 | nfs_access_add_cache(inode, &cache); |
| 1886 | out: | 1886 | out: |
| 1887 | if ((cache.mask & mask) == mask) | 1887 | if ((mask & ~cache.mask & (MAY_READ | MAY_WRITE | MAY_EXEC)) == 0) |
| 1888 | return 0; | 1888 | return 0; |
| 1889 | return -EACCES; | 1889 | return -EACCES; |
| 1890 | } | 1890 | } |
| @@ -1907,17 +1907,17 @@ int nfs_may_open(struct inode *inode, struct rpc_cred *cred, int openflags) | |||
| 1907 | return nfs_do_access(inode, cred, nfs_open_permission_mask(openflags)); | 1907 | return nfs_do_access(inode, cred, nfs_open_permission_mask(openflags)); |
| 1908 | } | 1908 | } |
| 1909 | 1909 | ||
| 1910 | int nfs_permission(struct inode *inode, int mask, struct nameidata *nd) | 1910 | int nfs_permission(struct inode *inode, int mask) |
| 1911 | { | 1911 | { |
| 1912 | struct rpc_cred *cred; | 1912 | struct rpc_cred *cred; |
| 1913 | int res = 0; | 1913 | int res = 0; |
| 1914 | 1914 | ||
| 1915 | nfs_inc_stats(inode, NFSIOS_VFSACCESS); | 1915 | nfs_inc_stats(inode, NFSIOS_VFSACCESS); |
| 1916 | 1916 | ||
| 1917 | if (mask == 0) | 1917 | if ((mask & (MAY_READ | MAY_WRITE | MAY_EXEC)) == 0) |
| 1918 | goto out; | 1918 | goto out; |
| 1919 | /* Is this sys_access() ? */ | 1919 | /* Is this sys_access() ? */ |
| 1920 | if (nd != NULL && (nd->flags & LOOKUP_ACCESS)) | 1920 | if (mask & MAY_ACCESS) |
| 1921 | goto force_lookup; | 1921 | goto force_lookup; |
| 1922 | 1922 | ||
| 1923 | switch (inode->i_mode & S_IFMT) { | 1923 | switch (inode->i_mode & S_IFMT) { |
| @@ -1926,8 +1926,7 @@ int nfs_permission(struct inode *inode, int mask, struct nameidata *nd) | |||
| 1926 | case S_IFREG: | 1926 | case S_IFREG: |
| 1927 | /* NFSv4 has atomic_open... */ | 1927 | /* NFSv4 has atomic_open... */ |
| 1928 | if (nfs_server_capable(inode, NFS_CAP_ATOMIC_OPEN) | 1928 | if (nfs_server_capable(inode, NFS_CAP_ATOMIC_OPEN) |
| 1929 | && nd != NULL | 1929 | && (mask & MAY_OPEN)) |
| 1930 | && (nd->flags & LOOKUP_OPEN)) | ||
| 1931 | goto out; | 1930 | goto out; |
| 1932 | break; | 1931 | break; |
| 1933 | case S_IFDIR: | 1932 | case S_IFDIR: |
diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c index e8514e8b6ce8..be2dd95d3a1d 100644 --- a/fs/ocfs2/file.c +++ b/fs/ocfs2/file.c | |||
| @@ -1176,7 +1176,7 @@ bail: | |||
| 1176 | return err; | 1176 | return err; |
| 1177 | } | 1177 | } |
| 1178 | 1178 | ||
| 1179 | int ocfs2_permission(struct inode *inode, int mask, struct nameidata *nd) | 1179 | int ocfs2_permission(struct inode *inode, int mask) |
| 1180 | { | 1180 | { |
| 1181 | int ret; | 1181 | int ret; |
| 1182 | 1182 | ||
diff --git a/fs/ocfs2/file.h b/fs/ocfs2/file.h index 048ddcaf5c80..1e27b4d017ea 100644 --- a/fs/ocfs2/file.h +++ b/fs/ocfs2/file.h | |||
| @@ -62,8 +62,7 @@ int ocfs2_lock_allocators(struct inode *inode, struct ocfs2_dinode *di, | |||
| 62 | int ocfs2_setattr(struct dentry *dentry, struct iattr *attr); | 62 | int ocfs2_setattr(struct dentry *dentry, struct iattr *attr); |
| 63 | int ocfs2_getattr(struct vfsmount *mnt, struct dentry *dentry, | 63 | int ocfs2_getattr(struct vfsmount *mnt, struct dentry *dentry, |
| 64 | struct kstat *stat); | 64 | struct kstat *stat); |
| 65 | int ocfs2_permission(struct inode *inode, int mask, | 65 | int ocfs2_permission(struct inode *inode, int mask); |
| 66 | struct nameidata *nd); | ||
| 67 | 66 | ||
| 68 | int ocfs2_should_update_atime(struct inode *inode, | 67 | int ocfs2_should_update_atime(struct inode *inode, |
| 69 | struct vfsmount *vfsmnt); | 68 | struct vfsmount *vfsmnt); |
diff --git a/fs/proc/base.c b/fs/proc/base.c index 81bce6791bfc..d82d800389f6 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c | |||
| @@ -1859,8 +1859,7 @@ static const struct file_operations proc_fd_operations = { | |||
| 1859 | * /proc/pid/fd needs a special permission handler so that a process can still | 1859 | * /proc/pid/fd needs a special permission handler so that a process can still |
| 1860 | * access /proc/self/fd after it has executed a setuid(). | 1860 | * access /proc/self/fd after it has executed a setuid(). |
| 1861 | */ | 1861 | */ |
| 1862 | static int proc_fd_permission(struct inode *inode, int mask, | 1862 | static int proc_fd_permission(struct inode *inode, int mask) |
| 1863 | struct nameidata *nd) | ||
| 1864 | { | 1863 | { |
| 1865 | int rv; | 1864 | int rv; |
| 1866 | 1865 | ||
diff --git a/fs/proc/proc_sysctl.c b/fs/proc/proc_sysctl.c index fa1ec2433e44..f9a8b892718f 100644 --- a/fs/proc/proc_sysctl.c +++ b/fs/proc/proc_sysctl.c | |||
| @@ -292,7 +292,7 @@ out: | |||
| 292 | return ret; | 292 | return ret; |
| 293 | } | 293 | } |
| 294 | 294 | ||
| 295 | static int proc_sys_permission(struct inode *inode, int mask, struct nameidata *nd) | 295 | static int proc_sys_permission(struct inode *inode, int mask) |
| 296 | { | 296 | { |
| 297 | /* | 297 | /* |
| 298 | * sysctl entries that are not writeable, | 298 | * sysctl entries that are not writeable, |
diff --git a/fs/reiserfs/xattr.c b/fs/reiserfs/xattr.c index d7c4935c1034..bb3cb5b7cdb2 100644 --- a/fs/reiserfs/xattr.c +++ b/fs/reiserfs/xattr.c | |||
| @@ -1250,7 +1250,7 @@ static int reiserfs_check_acl(struct inode *inode, int mask) | |||
| 1250 | return error; | 1250 | return error; |
| 1251 | } | 1251 | } |
| 1252 | 1252 | ||
| 1253 | int reiserfs_permission(struct inode *inode, int mask, struct nameidata *nd) | 1253 | int reiserfs_permission(struct inode *inode, int mask) |
| 1254 | { | 1254 | { |
| 1255 | /* | 1255 | /* |
| 1256 | * We don't do permission checks on the internal objects. | 1256 | * We don't do permission checks on the internal objects. |
diff --git a/fs/smbfs/file.c b/fs/smbfs/file.c index 2294783320cb..e4f8d51a5553 100644 --- a/fs/smbfs/file.c +++ b/fs/smbfs/file.c | |||
| @@ -408,7 +408,7 @@ smb_file_release(struct inode *inode, struct file * file) | |||
| 408 | * privileges, so we need our own check for this. | 408 | * privileges, so we need our own check for this. |
| 409 | */ | 409 | */ |
| 410 | static int | 410 | static int |
| 411 | smb_file_permission(struct inode *inode, int mask, struct nameidata *nd) | 411 | smb_file_permission(struct inode *inode, int mask) |
| 412 | { | 412 | { |
| 413 | int mode = inode->i_mode; | 413 | int mode = inode->i_mode; |
| 414 | int error = 0; | 414 | int error = 0; |
| @@ -417,7 +417,7 @@ smb_file_permission(struct inode *inode, int mask, struct nameidata *nd) | |||
| 417 | 417 | ||
| 418 | /* Look at user permissions */ | 418 | /* Look at user permissions */ |
| 419 | mode >>= 6; | 419 | mode >>= 6; |
| 420 | if ((mode & 7 & mask) != mask) | 420 | if (mask & ~mode & (MAY_READ | MAY_WRITE | MAY_EXEC)) |
| 421 | error = -EACCES; | 421 | error = -EACCES; |
| 422 | return error; | 422 | return error; |
| 423 | } | 423 | } |
diff --git a/fs/xfs/linux-2.6/xfs_iops.c b/fs/xfs/linux-2.6/xfs_iops.c index 2bf287ef5489..5fc61c824bb9 100644 --- a/fs/xfs/linux-2.6/xfs_iops.c +++ b/fs/xfs/linux-2.6/xfs_iops.c | |||
| @@ -589,8 +589,7 @@ xfs_check_acl( | |||
| 589 | STATIC int | 589 | STATIC int |
| 590 | xfs_vn_permission( | 590 | xfs_vn_permission( |
| 591 | struct inode *inode, | 591 | struct inode *inode, |
| 592 | int mask, | 592 | int mask) |
| 593 | struct nameidata *nd) | ||
| 594 | { | 593 | { |
| 595 | return generic_permission(inode, mask, xfs_check_acl); | 594 | return generic_permission(inode, mask, xfs_check_acl); |
| 596 | } | 595 | } |
diff --git a/include/linux/coda_linux.h b/include/linux/coda_linux.h index 31b75311e2ca..dcc228aa335a 100644 --- a/include/linux/coda_linux.h +++ b/include/linux/coda_linux.h | |||
| @@ -37,7 +37,7 @@ extern const struct file_operations coda_ioctl_operations; | |||
| 37 | /* operations shared over more than one file */ | 37 | /* operations shared over more than one file */ |
| 38 | int coda_open(struct inode *i, struct file *f); | 38 | int coda_open(struct inode *i, struct file *f); |
| 39 | int coda_release(struct inode *i, struct file *f); | 39 | int coda_release(struct inode *i, struct file *f); |
| 40 | int coda_permission(struct inode *inode, int mask, struct nameidata *nd); | 40 | int coda_permission(struct inode *inode, int mask); |
| 41 | int coda_revalidate_inode(struct dentry *); | 41 | int coda_revalidate_inode(struct dentry *); |
| 42 | int coda_getattr(struct vfsmount *, struct dentry *, struct kstat *); | 42 | int coda_getattr(struct vfsmount *, struct dentry *, struct kstat *); |
| 43 | int coda_setattr(struct dentry *, struct iattr *); | 43 | int coda_setattr(struct dentry *, struct iattr *); |
diff --git a/include/linux/fs.h b/include/linux/fs.h index 7721a2ac9c0e..6c923c9b79bc 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h | |||
| @@ -60,6 +60,9 @@ extern int dir_notify_enable; | |||
| 60 | #define MAY_WRITE 2 | 60 | #define MAY_WRITE 2 |
| 61 | #define MAY_READ 4 | 61 | #define MAY_READ 4 |
| 62 | #define MAY_APPEND 8 | 62 | #define MAY_APPEND 8 |
| 63 | #define MAY_ACCESS 16 | ||
| 64 | #define MAY_CHDIR 32 | ||
| 65 | #define MAY_OPEN 64 | ||
| 63 | 66 | ||
| 64 | #define FMODE_READ 1 | 67 | #define FMODE_READ 1 |
| 65 | #define FMODE_WRITE 2 | 68 | #define FMODE_WRITE 2 |
| @@ -1272,7 +1275,7 @@ struct inode_operations { | |||
| 1272 | void * (*follow_link) (struct dentry *, struct nameidata *); | 1275 | void * (*follow_link) (struct dentry *, struct nameidata *); |
| 1273 | void (*put_link) (struct dentry *, struct nameidata *, void *); | 1276 | void (*put_link) (struct dentry *, struct nameidata *, void *); |
| 1274 | void (*truncate) (struct inode *); | 1277 | void (*truncate) (struct inode *); |
| 1275 | int (*permission) (struct inode *, int, struct nameidata *); | 1278 | int (*permission) (struct inode *, int); |
| 1276 | int (*setattr) (struct dentry *, struct iattr *); | 1279 | int (*setattr) (struct dentry *, struct iattr *); |
| 1277 | int (*getattr) (struct vfsmount *mnt, struct dentry *, struct kstat *); | 1280 | int (*getattr) (struct vfsmount *mnt, struct dentry *, struct kstat *); |
| 1278 | int (*setxattr) (struct dentry *, const char *,const void *,size_t,int); | 1281 | int (*setxattr) (struct dentry *, const char *,const void *,size_t,int); |
diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h index 29d261918734..f08f9ca602af 100644 --- a/include/linux/nfs_fs.h +++ b/include/linux/nfs_fs.h | |||
| @@ -332,7 +332,7 @@ extern int nfs_refresh_inode(struct inode *, struct nfs_fattr *); | |||
| 332 | extern int nfs_post_op_update_inode(struct inode *inode, struct nfs_fattr *fattr); | 332 | extern int nfs_post_op_update_inode(struct inode *inode, struct nfs_fattr *fattr); |
| 333 | extern int nfs_post_op_update_inode_force_wcc(struct inode *inode, struct nfs_fattr *fattr); | 333 | extern int nfs_post_op_update_inode_force_wcc(struct inode *inode, struct nfs_fattr *fattr); |
| 334 | extern int nfs_getattr(struct vfsmount *, struct dentry *, struct kstat *); | 334 | extern int nfs_getattr(struct vfsmount *, struct dentry *, struct kstat *); |
| 335 | extern int nfs_permission(struct inode *, int, struct nameidata *); | 335 | extern int nfs_permission(struct inode *, int); |
| 336 | extern int nfs_open(struct inode *, struct file *); | 336 | extern int nfs_open(struct inode *, struct file *); |
| 337 | extern int nfs_release(struct inode *, struct file *); | 337 | extern int nfs_release(struct inode *, struct file *); |
| 338 | extern int nfs_attribute_timeout(struct inode *inode); | 338 | extern int nfs_attribute_timeout(struct inode *inode); |
diff --git a/include/linux/reiserfs_xattr.h b/include/linux/reiserfs_xattr.h index 66a96814d614..af135ae895db 100644 --- a/include/linux/reiserfs_xattr.h +++ b/include/linux/reiserfs_xattr.h | |||
| @@ -55,7 +55,7 @@ int reiserfs_removexattr(struct dentry *dentry, const char *name); | |||
| 55 | int reiserfs_delete_xattrs(struct inode *inode); | 55 | int reiserfs_delete_xattrs(struct inode *inode); |
| 56 | int reiserfs_chown_xattrs(struct inode *inode, struct iattr *attrs); | 56 | int reiserfs_chown_xattrs(struct inode *inode, struct iattr *attrs); |
| 57 | int reiserfs_xattr_init(struct super_block *sb, int mount_flags); | 57 | int reiserfs_xattr_init(struct super_block *sb, int mount_flags); |
| 58 | int reiserfs_permission(struct inode *inode, int mask, struct nameidata *nd); | 58 | int reiserfs_permission(struct inode *inode, int mask); |
| 59 | 59 | ||
| 60 | int reiserfs_xattr_del(struct inode *, const char *); | 60 | int reiserfs_xattr_del(struct inode *, const char *); |
| 61 | int reiserfs_xattr_get(const struct inode *, const char *, void *, size_t); | 61 | int reiserfs_xattr_get(const struct inode *, const char *, void *, size_t); |
diff --git a/include/linux/shmem_fs.h b/include/linux/shmem_fs.h index f2d12d5a21b8..fd83f2584b15 100644 --- a/include/linux/shmem_fs.h +++ b/include/linux/shmem_fs.h | |||
| @@ -43,7 +43,7 @@ static inline struct shmem_inode_info *SHMEM_I(struct inode *inode) | |||
| 43 | } | 43 | } |
| 44 | 44 | ||
| 45 | #ifdef CONFIG_TMPFS_POSIX_ACL | 45 | #ifdef CONFIG_TMPFS_POSIX_ACL |
| 46 | int shmem_permission(struct inode *, int, struct nameidata *); | 46 | int shmem_permission(struct inode *, int); |
| 47 | int shmem_acl_init(struct inode *, struct inode *); | 47 | int shmem_acl_init(struct inode *, struct inode *); |
| 48 | void shmem_acl_destroy_inode(struct inode *); | 48 | void shmem_acl_destroy_inode(struct inode *); |
| 49 | 49 | ||
diff --git a/kernel/sysctl.c b/kernel/sysctl.c index ff5abcca5ddf..911d846f0503 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c | |||
| @@ -1516,9 +1516,9 @@ static int do_sysctl_strategy(struct ctl_table_root *root, | |||
| 1516 | int op = 0, rc; | 1516 | int op = 0, rc; |
| 1517 | 1517 | ||
| 1518 | if (oldval) | 1518 | if (oldval) |
| 1519 | op |= 004; | 1519 | op |= MAY_READ; |
| 1520 | if (newval) | 1520 | if (newval) |
| 1521 | op |= 002; | 1521 | op |= MAY_WRITE; |
| 1522 | if (sysctl_perm(root, table, op)) | 1522 | if (sysctl_perm(root, table, op)) |
| 1523 | return -EPERM; | 1523 | return -EPERM; |
| 1524 | 1524 | ||
| @@ -1560,7 +1560,7 @@ repeat: | |||
| 1560 | if (n == table->ctl_name) { | 1560 | if (n == table->ctl_name) { |
| 1561 | int error; | 1561 | int error; |
| 1562 | if (table->child) { | 1562 | if (table->child) { |
| 1563 | if (sysctl_perm(root, table, 001)) | 1563 | if (sysctl_perm(root, table, MAY_EXEC)) |
| 1564 | return -EPERM; | 1564 | return -EPERM; |
| 1565 | name++; | 1565 | name++; |
| 1566 | nlen--; | 1566 | nlen--; |
| @@ -1635,7 +1635,7 @@ static int test_perm(int mode, int op) | |||
| 1635 | mode >>= 6; | 1635 | mode >>= 6; |
| 1636 | else if (in_egroup_p(0)) | 1636 | else if (in_egroup_p(0)) |
| 1637 | mode >>= 3; | 1637 | mode >>= 3; |
| 1638 | if ((mode & op & 0007) == op) | 1638 | if ((op & ~mode & (MAY_READ|MAY_WRITE|MAY_EXEC)) == 0) |
| 1639 | return 0; | 1639 | return 0; |
| 1640 | return -EACCES; | 1640 | return -EACCES; |
| 1641 | } | 1641 | } |
| @@ -1645,7 +1645,7 @@ int sysctl_perm(struct ctl_table_root *root, struct ctl_table *table, int op) | |||
| 1645 | int error; | 1645 | int error; |
| 1646 | int mode; | 1646 | int mode; |
| 1647 | 1647 | ||
| 1648 | error = security_sysctl(table, op); | 1648 | error = security_sysctl(table, op & (MAY_READ | MAY_WRITE | MAY_EXEC)); |
| 1649 | if (error) | 1649 | if (error) |
| 1650 | return error; | 1650 | return error; |
| 1651 | 1651 | ||
diff --git a/mm/shmem_acl.c b/mm/shmem_acl.c index f5664c5b9eb1..8e5aadd7dcd6 100644 --- a/mm/shmem_acl.c +++ b/mm/shmem_acl.c | |||
| @@ -191,7 +191,7 @@ shmem_check_acl(struct inode *inode, int mask) | |||
| 191 | * shmem_permission - permission() inode operation | 191 | * shmem_permission - permission() inode operation |
| 192 | */ | 192 | */ |
| 193 | int | 193 | int |
| 194 | shmem_permission(struct inode *inode, int mask, struct nameidata *nd) | 194 | shmem_permission(struct inode *inode, int mask) |
| 195 | { | 195 | { |
| 196 | return generic_permission(inode, mask, shmem_check_acl); | 196 | return generic_permission(inode, mask, shmem_check_acl); |
| 197 | } | 197 | } |
