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 /fs | |
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>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/afs/internal.h | 4 | ||||
-rw-r--r-- | fs/afs/security.c | 2 | ||||
-rw-r--r-- | fs/bad_inode.c | 3 | ||||
-rw-r--r-- | fs/cifs/cifsfs.c | 2 | ||||
-rw-r--r-- | fs/coda/dir.c | 4 | ||||
-rw-r--r-- | fs/coda/pioctl.c | 6 | ||||
-rw-r--r-- | fs/ecryptfs/inode.c | 17 | ||||
-rw-r--r-- | fs/ext2/acl.c | 2 | ||||
-rw-r--r-- | fs/ext2/acl.h | 2 | ||||
-rw-r--r-- | fs/ext3/acl.c | 2 | ||||
-rw-r--r-- | fs/ext3/acl.h | 2 | ||||
-rw-r--r-- | fs/ext4/acl.c | 2 | ||||
-rw-r--r-- | fs/ext4/acl.h | 2 | ||||
-rw-r--r-- | fs/fuse/dir.c | 6 | ||||
-rw-r--r-- | fs/gfs2/ops_inode.c | 12 | ||||
-rw-r--r-- | fs/hfs/inode.c | 3 | ||||
-rw-r--r-- | fs/hfsplus/inode.c | 2 | ||||
-rw-r--r-- | fs/hostfs/hostfs_kern.c | 2 | ||||
-rw-r--r-- | fs/jffs2/acl.c | 2 | ||||
-rw-r--r-- | fs/jffs2/acl.h | 2 | ||||
-rw-r--r-- | fs/jfs/acl.c | 2 | ||||
-rw-r--r-- | fs/jfs/jfs_acl.h | 2 | ||||
-rw-r--r-- | fs/namei.c | 23 | ||||
-rw-r--r-- | fs/nfs/dir.c | 11 | ||||
-rw-r--r-- | fs/ocfs2/file.c | 2 | ||||
-rw-r--r-- | fs/ocfs2/file.h | 3 | ||||
-rw-r--r-- | fs/proc/base.c | 3 | ||||
-rw-r--r-- | fs/proc/proc_sysctl.c | 2 | ||||
-rw-r--r-- | fs/reiserfs/xattr.c | 2 | ||||
-rw-r--r-- | fs/smbfs/file.c | 4 | ||||
-rw-r--r-- | fs/xfs/linux-2.6/xfs_iops.c | 3 |
31 files changed, 60 insertions, 76 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 | } |