diff options
author | Christoph Hellwig <hch@lst.de> | 2005-11-09 00:35:04 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2005-11-09 10:55:59 -0500 |
commit | 8c744fb83da0771afa04695028e3550b798dad90 (patch) | |
tree | 670896a1c2594965099853a6c992907abb3a886f | |
parent | e4543eddfd3bf3e0d625841377fa695a519edfd4 (diff) |
[PATCH] add a file_permission helper
A few more callers of permission() just want to check for a different access
pattern on an already open file. This patch adds a wrapper for permission()
that takes a file in preparation of per-mount read-only support and to clean
up the callers a little. The helper is not intended for new code, everything
without the interface set in stone should use vfs_permission()
Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r-- | drivers/block/floppy.c | 3 | ||||
-rw-r--r-- | fs/binfmt_misc.c | 2 | ||||
-rw-r--r-- | fs/exec.c | 2 | ||||
-rw-r--r-- | fs/namei.c | 18 | ||||
-rw-r--r-- | fs/ncpfs/ioctl.c | 34 | ||||
-rw-r--r-- | fs/open.c | 2 | ||||
-rw-r--r-- | fs/udf/file.c | 2 | ||||
-rw-r--r-- | include/linux/fs.h | 5 |
8 files changed, 47 insertions, 21 deletions
diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c index dd1935d55424..28002de783b6 100644 --- a/drivers/block/floppy.c +++ b/drivers/block/floppy.c | |||
@@ -3776,8 +3776,7 @@ static int floppy_open(struct inode *inode, struct file *filp) | |||
3776 | /* Allow ioctls if we have write-permissions even if read-only open. | 3776 | /* Allow ioctls if we have write-permissions even if read-only open. |
3777 | * Needed so that programs such as fdrawcmd still can work on write | 3777 | * Needed so that programs such as fdrawcmd still can work on write |
3778 | * protected disks */ | 3778 | * protected disks */ |
3779 | if (filp->f_mode & 2 | 3779 | if ((filp->f_mode & FMODE_WRITE) || !file_permission(filp, MAY_WRITE)) |
3780 | || permission(filp->f_dentry->d_inode, 2, NULL) == 0) | ||
3781 | filp->private_data = (void *)8; | 3780 | filp->private_data = (void *)8; |
3782 | 3781 | ||
3783 | if (UFDCS->rawcmd == 1) | 3782 | if (UFDCS->rawcmd == 1) |
diff --git a/fs/binfmt_misc.c b/fs/binfmt_misc.c index 8ae0db6cd69c..2568eb41cb3a 100644 --- a/fs/binfmt_misc.c +++ b/fs/binfmt_misc.c | |||
@@ -150,7 +150,7 @@ static int load_misc_binary(struct linux_binprm *bprm, struct pt_regs *regs) | |||
150 | 150 | ||
151 | /* if the binary is not readable than enforce mm->dumpable=0 | 151 | /* if the binary is not readable than enforce mm->dumpable=0 |
152 | regardless of the interpreter's permissions */ | 152 | regardless of the interpreter's permissions */ |
153 | if (permission(bprm->file->f_dentry->d_inode, MAY_READ, NULL)) | 153 | if (file_permission(bprm->file, MAY_READ)) |
154 | bprm->interp_flags |= BINPRM_FLAGS_ENFORCE_NONDUMP; | 154 | bprm->interp_flags |= BINPRM_FLAGS_ENFORCE_NONDUMP; |
155 | 155 | ||
156 | allow_write_access(bprm->file); | 156 | allow_write_access(bprm->file); |
@@ -896,7 +896,7 @@ int flush_old_exec(struct linux_binprm * bprm) | |||
896 | flush_thread(); | 896 | flush_thread(); |
897 | 897 | ||
898 | if (bprm->e_uid != current->euid || bprm->e_gid != current->egid || | 898 | if (bprm->e_uid != current->euid || bprm->e_gid != current->egid || |
899 | permission(bprm->file->f_dentry->d_inode,MAY_READ, NULL) || | 899 | file_permission(bprm->file, MAY_READ) || |
900 | (bprm->interp_flags & BINPRM_FLAGS_ENFORCE_NONDUMP)) { | 900 | (bprm->interp_flags & BINPRM_FLAGS_ENFORCE_NONDUMP)) { |
901 | suid_keys(current); | 901 | suid_keys(current); |
902 | current->mm->dumpable = suid_dumpable; | 902 | current->mm->dumpable = suid_dumpable; |
diff --git a/fs/namei.c b/fs/namei.c index 25e4ab4ce8b7..b69f6ebadb95 100644 --- a/fs/namei.c +++ b/fs/namei.c | |||
@@ -271,6 +271,23 @@ int vfs_permission(struct nameidata *nd, int mask) | |||
271 | return permission(nd->dentry->d_inode, mask, nd); | 271 | return permission(nd->dentry->d_inode, mask, nd); |
272 | } | 272 | } |
273 | 273 | ||
274 | /** | ||
275 | * file_permission - check for additional access rights to a given file | ||
276 | * @file: file to check access rights for | ||
277 | * @mask: right to check for (%MAY_READ, %MAY_WRITE, %MAY_EXEC) | ||
278 | * | ||
279 | * Used to check for read/write/execute permissions on an already opened | ||
280 | * file. | ||
281 | * | ||
282 | * Note: | ||
283 | * Do not use this function in new code. All access checks should | ||
284 | * be done using vfs_permission(). | ||
285 | */ | ||
286 | int file_permission(struct file *file, int mask) | ||
287 | { | ||
288 | return permission(file->f_dentry->d_inode, mask, NULL); | ||
289 | } | ||
290 | |||
274 | /* | 291 | /* |
275 | * get_write_access() gets write permission for a file. | 292 | * get_write_access() gets write permission for a file. |
276 | * put_write_access() releases this write permission. | 293 | * put_write_access() releases this write permission. |
@@ -2551,6 +2568,7 @@ EXPORT_SYMBOL(path_release); | |||
2551 | EXPORT_SYMBOL(path_walk); | 2568 | EXPORT_SYMBOL(path_walk); |
2552 | EXPORT_SYMBOL(permission); | 2569 | EXPORT_SYMBOL(permission); |
2553 | EXPORT_SYMBOL(vfs_permission); | 2570 | EXPORT_SYMBOL(vfs_permission); |
2571 | EXPORT_SYMBOL(file_permission); | ||
2554 | EXPORT_SYMBOL(unlock_rename); | 2572 | EXPORT_SYMBOL(unlock_rename); |
2555 | EXPORT_SYMBOL(vfs_create); | 2573 | EXPORT_SYMBOL(vfs_create); |
2556 | EXPORT_SYMBOL(vfs_follow_link); | 2574 | EXPORT_SYMBOL(vfs_follow_link); |
diff --git a/fs/ncpfs/ioctl.c b/fs/ncpfs/ioctl.c index 88df79356a1f..fd3efdca5ae3 100644 --- a/fs/ncpfs/ioctl.c +++ b/fs/ncpfs/ioctl.c | |||
@@ -30,11 +30,13 @@ | |||
30 | #define NCP_PACKET_SIZE_INTERNAL 65536 | 30 | #define NCP_PACKET_SIZE_INTERNAL 65536 |
31 | 31 | ||
32 | static int | 32 | static int |
33 | ncp_get_fs_info(struct ncp_server* server, struct inode* inode, struct ncp_fs_info __user *arg) | 33 | ncp_get_fs_info(struct ncp_server * server, struct file *file, |
34 | struct ncp_fs_info __user *arg) | ||
34 | { | 35 | { |
36 | struct inode *inode = file->f_dentry->d_inode; | ||
35 | struct ncp_fs_info info; | 37 | struct ncp_fs_info info; |
36 | 38 | ||
37 | if ((permission(inode, MAY_WRITE, NULL) != 0) | 39 | if ((file_permission(file, MAY_WRITE) != 0) |
38 | && (current->uid != server->m.mounted_uid)) { | 40 | && (current->uid != server->m.mounted_uid)) { |
39 | return -EACCES; | 41 | return -EACCES; |
40 | } | 42 | } |
@@ -58,11 +60,13 @@ ncp_get_fs_info(struct ncp_server* server, struct inode* inode, struct ncp_fs_in | |||
58 | } | 60 | } |
59 | 61 | ||
60 | static int | 62 | static int |
61 | ncp_get_fs_info_v2(struct ncp_server* server, struct inode* inode, struct ncp_fs_info_v2 __user * arg) | 63 | ncp_get_fs_info_v2(struct ncp_server * server, struct file *file, |
64 | struct ncp_fs_info_v2 __user * arg) | ||
62 | { | 65 | { |
66 | struct inode *inode = file->f_dentry->d_inode; | ||
63 | struct ncp_fs_info_v2 info2; | 67 | struct ncp_fs_info_v2 info2; |
64 | 68 | ||
65 | if ((permission(inode, MAY_WRITE, NULL) != 0) | 69 | if ((file_permission(file, MAY_WRITE) != 0) |
66 | && (current->uid != server->m.mounted_uid)) { | 70 | && (current->uid != server->m.mounted_uid)) { |
67 | return -EACCES; | 71 | return -EACCES; |
68 | } | 72 | } |
@@ -190,7 +194,7 @@ int ncp_ioctl(struct inode *inode, struct file *filp, | |||
190 | switch (cmd) { | 194 | switch (cmd) { |
191 | case NCP_IOC_NCPREQUEST: | 195 | case NCP_IOC_NCPREQUEST: |
192 | 196 | ||
193 | if ((permission(inode, MAY_WRITE, NULL) != 0) | 197 | if ((file_permission(filp, MAY_WRITE) != 0) |
194 | && (current->uid != server->m.mounted_uid)) { | 198 | && (current->uid != server->m.mounted_uid)) { |
195 | return -EACCES; | 199 | return -EACCES; |
196 | } | 200 | } |
@@ -245,16 +249,16 @@ int ncp_ioctl(struct inode *inode, struct file *filp, | |||
245 | return ncp_conn_logged_in(inode->i_sb); | 249 | return ncp_conn_logged_in(inode->i_sb); |
246 | 250 | ||
247 | case NCP_IOC_GET_FS_INFO: | 251 | case NCP_IOC_GET_FS_INFO: |
248 | return ncp_get_fs_info(server, inode, argp); | 252 | return ncp_get_fs_info(server, filp, argp); |
249 | 253 | ||
250 | case NCP_IOC_GET_FS_INFO_V2: | 254 | case NCP_IOC_GET_FS_INFO_V2: |
251 | return ncp_get_fs_info_v2(server, inode, argp); | 255 | return ncp_get_fs_info_v2(server, filp, argp); |
252 | 256 | ||
253 | case NCP_IOC_GETMOUNTUID2: | 257 | case NCP_IOC_GETMOUNTUID2: |
254 | { | 258 | { |
255 | unsigned long tmp = server->m.mounted_uid; | 259 | unsigned long tmp = server->m.mounted_uid; |
256 | 260 | ||
257 | if ( (permission(inode, MAY_READ, NULL) != 0) | 261 | if ((file_permission(filp, MAY_READ) != 0) |
258 | && (current->uid != server->m.mounted_uid)) | 262 | && (current->uid != server->m.mounted_uid)) |
259 | { | 263 | { |
260 | return -EACCES; | 264 | return -EACCES; |
@@ -268,7 +272,7 @@ int ncp_ioctl(struct inode *inode, struct file *filp, | |||
268 | { | 272 | { |
269 | struct ncp_setroot_ioctl sr; | 273 | struct ncp_setroot_ioctl sr; |
270 | 274 | ||
271 | if ( (permission(inode, MAY_READ, NULL) != 0) | 275 | if ((file_permission(filp, MAY_READ) != 0) |
272 | && (current->uid != server->m.mounted_uid)) | 276 | && (current->uid != server->m.mounted_uid)) |
273 | { | 277 | { |
274 | return -EACCES; | 278 | return -EACCES; |
@@ -343,7 +347,7 @@ int ncp_ioctl(struct inode *inode, struct file *filp, | |||
343 | 347 | ||
344 | #ifdef CONFIG_NCPFS_PACKET_SIGNING | 348 | #ifdef CONFIG_NCPFS_PACKET_SIGNING |
345 | case NCP_IOC_SIGN_INIT: | 349 | case NCP_IOC_SIGN_INIT: |
346 | if ((permission(inode, MAY_WRITE, NULL) != 0) | 350 | if ((file_permission(filp, MAY_WRITE) != 0) |
347 | && (current->uid != server->m.mounted_uid)) | 351 | && (current->uid != server->m.mounted_uid)) |
348 | { | 352 | { |
349 | return -EACCES; | 353 | return -EACCES; |
@@ -366,7 +370,7 @@ int ncp_ioctl(struct inode *inode, struct file *filp, | |||
366 | return 0; | 370 | return 0; |
367 | 371 | ||
368 | case NCP_IOC_SIGN_WANTED: | 372 | case NCP_IOC_SIGN_WANTED: |
369 | if ( (permission(inode, MAY_READ, NULL) != 0) | 373 | if ((file_permission(filp, MAY_READ) != 0) |
370 | && (current->uid != server->m.mounted_uid)) | 374 | && (current->uid != server->m.mounted_uid)) |
371 | { | 375 | { |
372 | return -EACCES; | 376 | return -EACCES; |
@@ -379,7 +383,7 @@ int ncp_ioctl(struct inode *inode, struct file *filp, | |||
379 | { | 383 | { |
380 | int newstate; | 384 | int newstate; |
381 | 385 | ||
382 | if ( (permission(inode, MAY_WRITE, NULL) != 0) | 386 | if ((file_permission(filp, MAY_WRITE) != 0) |
383 | && (current->uid != server->m.mounted_uid)) | 387 | && (current->uid != server->m.mounted_uid)) |
384 | { | 388 | { |
385 | return -EACCES; | 389 | return -EACCES; |
@@ -400,7 +404,7 @@ int ncp_ioctl(struct inode *inode, struct file *filp, | |||
400 | 404 | ||
401 | #ifdef CONFIG_NCPFS_IOCTL_LOCKING | 405 | #ifdef CONFIG_NCPFS_IOCTL_LOCKING |
402 | case NCP_IOC_LOCKUNLOCK: | 406 | case NCP_IOC_LOCKUNLOCK: |
403 | if ( (permission(inode, MAY_WRITE, NULL) != 0) | 407 | if ((file_permission(filp, MAY_WRITE) != 0) |
404 | && (current->uid != server->m.mounted_uid)) | 408 | && (current->uid != server->m.mounted_uid)) |
405 | { | 409 | { |
406 | return -EACCES; | 410 | return -EACCES; |
@@ -605,7 +609,7 @@ outrel: | |||
605 | #endif /* CONFIG_NCPFS_NLS */ | 609 | #endif /* CONFIG_NCPFS_NLS */ |
606 | 610 | ||
607 | case NCP_IOC_SETDENTRYTTL: | 611 | case NCP_IOC_SETDENTRYTTL: |
608 | if ((permission(inode, MAY_WRITE, NULL) != 0) && | 612 | if ((file_permission(filp, MAY_WRITE) != 0) && |
609 | (current->uid != server->m.mounted_uid)) | 613 | (current->uid != server->m.mounted_uid)) |
610 | return -EACCES; | 614 | return -EACCES; |
611 | { | 615 | { |
@@ -635,7 +639,7 @@ outrel: | |||
635 | so we have this out of switch */ | 639 | so we have this out of switch */ |
636 | if (cmd == NCP_IOC_GETMOUNTUID) { | 640 | if (cmd == NCP_IOC_GETMOUNTUID) { |
637 | __kernel_uid_t uid = 0; | 641 | __kernel_uid_t uid = 0; |
638 | if ((permission(inode, MAY_READ, NULL) != 0) | 642 | if ((file_permission(filp, MAY_READ) != 0) |
639 | && (current->uid != server->m.mounted_uid)) { | 643 | && (current->uid != server->m.mounted_uid)) { |
640 | return -EACCES; | 644 | return -EACCES; |
641 | } | 645 | } |
@@ -563,7 +563,7 @@ asmlinkage long sys_fchdir(unsigned int fd) | |||
563 | if (!S_ISDIR(inode->i_mode)) | 563 | if (!S_ISDIR(inode->i_mode)) |
564 | goto out_putf; | 564 | goto out_putf; |
565 | 565 | ||
566 | error = permission(inode, MAY_EXEC, NULL); | 566 | error = file_permission(file, MAY_EXEC); |
567 | if (!error) | 567 | if (!error) |
568 | set_fs_pwd(current->fs, mnt, dentry); | 568 | set_fs_pwd(current->fs, mnt, dentry); |
569 | out_putf: | 569 | out_putf: |
diff --git a/fs/udf/file.c b/fs/udf/file.c index bb40d63f328f..01f520c71dc1 100644 --- a/fs/udf/file.c +++ b/fs/udf/file.c | |||
@@ -186,7 +186,7 @@ int udf_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, | |||
186 | { | 186 | { |
187 | int result = -EINVAL; | 187 | int result = -EINVAL; |
188 | 188 | ||
189 | if ( permission(inode, MAY_READ, NULL) != 0 ) | 189 | if ( file_permission(filp, MAY_READ) != 0 ) |
190 | { | 190 | { |
191 | udf_debug("no permission to access inode %lu\n", | 191 | udf_debug("no permission to access inode %lu\n", |
192 | inode->i_ino); | 192 | inode->i_ino); |
diff --git a/include/linux/fs.h b/include/linux/fs.h index c3b8c1dc7cdf..cc35b6ac778d 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h | |||
@@ -890,6 +890,11 @@ extern int vfs_rename(struct inode *, struct dentry *, struct inode *, struct de | |||
890 | extern void dentry_unhash(struct dentry *dentry); | 890 | extern void dentry_unhash(struct dentry *dentry); |
891 | 891 | ||
892 | /* | 892 | /* |
893 | * VFS file helper functions. | ||
894 | */ | ||
895 | extern int file_permission(struct file *, int); | ||
896 | |||
897 | /* | ||
893 | * File types | 898 | * File types |
894 | * | 899 | * |
895 | * NOTE! These match bits 12..15 of stat.st_mode | 900 | * NOTE! These match bits 12..15 of stat.st_mode |