aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@lst.de>2005-11-09 00:35:04 -0500
committerLinus Torvalds <torvalds@g5.osdl.org>2005-11-09 10:55:58 -0500
commite4543eddfd3bf3e0d625841377fa695a519edfd4 (patch)
treeb62546cb0038529bd8cd583333c556ad799f2081
parente4a53cbabc81f04e24a5570b4aa6a6384bdbfc67 (diff)
[PATCH] add a vfs_permission helper
Most permission() calls have a struct nameidata * available. This helper takes that as an argument and thus makes sure we pass it down for lookup intents and prepares for per-mount read-only support where we need a struct vfsmount for checking whether a file is writeable. 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--fs/exec.c4
-rw-r--r--fs/inotify.c2
-rw-r--r--fs/namei.c23
-rw-r--r--fs/namespace.c2
-rw-r--r--fs/open.c12
-rw-r--r--include/linux/fs.h1
-rw-r--r--net/unix/af_unix.c2
7 files changed, 31 insertions, 15 deletions
diff --git a/fs/exec.c b/fs/exec.c
index 5a4e3acc2e9f..7bbb781b9ac6 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -135,7 +135,7 @@ asmlinkage long sys_uselib(const char __user * library)
135 if (!S_ISREG(nd.dentry->d_inode->i_mode)) 135 if (!S_ISREG(nd.dentry->d_inode->i_mode))
136 goto exit; 136 goto exit;
137 137
138 error = permission(nd.dentry->d_inode, MAY_READ | MAY_EXEC, &nd); 138 error = vfs_permission(&nd, MAY_READ | MAY_EXEC);
139 if (error) 139 if (error)
140 goto exit; 140 goto exit;
141 141
@@ -495,7 +495,7 @@ struct file *open_exec(const char *name)
495 file = ERR_PTR(-EACCES); 495 file = ERR_PTR(-EACCES);
496 if (!(nd.mnt->mnt_flags & MNT_NOEXEC) && 496 if (!(nd.mnt->mnt_flags & MNT_NOEXEC) &&
497 S_ISREG(inode->i_mode)) { 497 S_ISREG(inode->i_mode)) {
498 int err = permission(inode, MAY_EXEC, &nd); 498 int err = vfs_permission(&nd, MAY_EXEC);
499 if (!err && !(inode->i_mode & 0111)) 499 if (!err && !(inode->i_mode & 0111))
500 err = -EACCES; 500 err = -EACCES;
501 file = ERR_PTR(err); 501 file = ERR_PTR(err);
diff --git a/fs/inotify.c b/fs/inotify.c
index 9fbaebfdf40b..bf7ce1d2412b 100644
--- a/fs/inotify.c
+++ b/fs/inotify.c
@@ -372,7 +372,7 @@ static int find_inode(const char __user *dirname, struct nameidata *nd)
372 if (error) 372 if (error)
373 return error; 373 return error;
374 /* you can only watch an inode if you have read permissions on it */ 374 /* you can only watch an inode if you have read permissions on it */
375 error = permission(nd->dentry->d_inode, MAY_READ, NULL); 375 error = vfs_permission(nd, MAY_READ);
376 if (error) 376 if (error)
377 path_release(nd); 377 path_release(nd);
378 return error; 378 return error;
diff --git a/fs/namei.c b/fs/namei.c
index b3f8a1966c9c..25e4ab4ce8b7 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -256,6 +256,21 @@ int permission(struct inode *inode, int mask, struct nameidata *nd)
256 return security_inode_permission(inode, mask, nd); 256 return security_inode_permission(inode, mask, nd);
257} 257}
258 258
259/**
260 * vfs_permission - check for access rights to a given path
261 * @nd: lookup result that describes the path
262 * @mask: right to check for (%MAY_READ, %MAY_WRITE, %MAY_EXEC)
263 *
264 * Used to check for read/write/execute permissions on a path.
265 * We use "fsuid" for this, letting us set arbitrary permissions
266 * for filesystem access without changing the "normal" uids which
267 * are used for other things.
268 */
269int vfs_permission(struct nameidata *nd, int mask)
270{
271 return permission(nd->dentry->d_inode, mask, nd);
272}
273
259/* 274/*
260 * get_write_access() gets write permission for a file. 275 * get_write_access() gets write permission for a file.
261 * put_write_access() releases this write permission. 276 * put_write_access() releases this write permission.
@@ -765,9 +780,8 @@ static fastcall int __link_path_walk(const char * name, struct nameidata *nd)
765 780
766 nd->flags |= LOOKUP_CONTINUE; 781 nd->flags |= LOOKUP_CONTINUE;
767 err = exec_permission_lite(inode, nd); 782 err = exec_permission_lite(inode, nd);
768 if (err == -EAGAIN) { 783 if (err == -EAGAIN)
769 err = permission(inode, MAY_EXEC, nd); 784 err = vfs_permission(nd, MAY_EXEC);
770 }
771 if (err) 785 if (err)
772 break; 786 break;
773 787
@@ -1407,7 +1421,7 @@ int may_open(struct nameidata *nd, int acc_mode, int flag)
1407 if (S_ISDIR(inode->i_mode) && (flag & FMODE_WRITE)) 1421 if (S_ISDIR(inode->i_mode) && (flag & FMODE_WRITE))
1408 return -EISDIR; 1422 return -EISDIR;
1409 1423
1410 error = permission(inode, acc_mode, nd); 1424 error = vfs_permission(nd, acc_mode);
1411 if (error) 1425 if (error)
1412 return error; 1426 return error;
1413 1427
@@ -2536,6 +2550,7 @@ EXPORT_SYMBOL(path_lookup);
2536EXPORT_SYMBOL(path_release); 2550EXPORT_SYMBOL(path_release);
2537EXPORT_SYMBOL(path_walk); 2551EXPORT_SYMBOL(path_walk);
2538EXPORT_SYMBOL(permission); 2552EXPORT_SYMBOL(permission);
2553EXPORT_SYMBOL(vfs_permission);
2539EXPORT_SYMBOL(unlock_rename); 2554EXPORT_SYMBOL(unlock_rename);
2540EXPORT_SYMBOL(vfs_create); 2555EXPORT_SYMBOL(vfs_create);
2541EXPORT_SYMBOL(vfs_follow_link); 2556EXPORT_SYMBOL(vfs_follow_link);
diff --git a/fs/namespace.c b/fs/namespace.c
index caa9187f67e5..2019899f2ab8 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -637,7 +637,7 @@ static int mount_is_safe(struct nameidata *nd)
637 if (current->uid != nd->dentry->d_inode->i_uid) 637 if (current->uid != nd->dentry->d_inode->i_uid)
638 return -EPERM; 638 return -EPERM;
639 } 639 }
640 if (permission(nd->dentry->d_inode, MAY_WRITE, nd)) 640 if (vfs_permission(nd, MAY_WRITE))
641 return -EPERM; 641 return -EPERM;
642 return 0; 642 return 0;
643#endif 643#endif
diff --git a/fs/open.c b/fs/open.c
index 6e8136751e9a..baffc084580d 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -240,7 +240,7 @@ static inline long do_sys_truncate(const char __user * path, loff_t length)
240 if (!S_ISREG(inode->i_mode)) 240 if (!S_ISREG(inode->i_mode))
241 goto dput_and_out; 241 goto dput_and_out;
242 242
243 error = permission(inode,MAY_WRITE,&nd); 243 error = vfs_permission(&nd, MAY_WRITE);
244 if (error) 244 if (error)
245 goto dput_and_out; 245 goto dput_and_out;
246 246
@@ -394,7 +394,7 @@ asmlinkage long sys_utime(char __user * filename, struct utimbuf __user * times)
394 goto dput_and_out; 394 goto dput_and_out;
395 395
396 if (current->fsuid != inode->i_uid && 396 if (current->fsuid != inode->i_uid &&
397 (error = permission(inode,MAY_WRITE,&nd)) != 0) 397 (error = vfs_permission(&nd, MAY_WRITE)) != 0)
398 goto dput_and_out; 398 goto dput_and_out;
399 } 399 }
400 down(&inode->i_sem); 400 down(&inode->i_sem);
@@ -447,7 +447,7 @@ long do_utimes(char __user * filename, struct timeval * times)
447 goto dput_and_out; 447 goto dput_and_out;
448 448
449 if (current->fsuid != inode->i_uid && 449 if (current->fsuid != inode->i_uid &&
450 (error = permission(inode,MAY_WRITE,&nd)) != 0) 450 (error = vfs_permission(&nd, MAY_WRITE)) != 0)
451 goto dput_and_out; 451 goto dput_and_out;
452 } 452 }
453 down(&inode->i_sem); 453 down(&inode->i_sem);
@@ -506,7 +506,7 @@ asmlinkage long sys_access(const char __user * filename, int mode)
506 506
507 res = __user_walk(filename, LOOKUP_FOLLOW|LOOKUP_ACCESS, &nd); 507 res = __user_walk(filename, LOOKUP_FOLLOW|LOOKUP_ACCESS, &nd);
508 if (!res) { 508 if (!res) {
509 res = permission(nd.dentry->d_inode, mode, &nd); 509 res = vfs_permission(&nd, mode);
510 /* SuS v2 requires we report a read only fs too */ 510 /* SuS v2 requires we report a read only fs too */
511 if(!res && (mode & S_IWOTH) && IS_RDONLY(nd.dentry->d_inode) 511 if(!res && (mode & S_IWOTH) && IS_RDONLY(nd.dentry->d_inode)
512 && !special_file(nd.dentry->d_inode->i_mode)) 512 && !special_file(nd.dentry->d_inode->i_mode))
@@ -530,7 +530,7 @@ asmlinkage long sys_chdir(const char __user * filename)
530 if (error) 530 if (error)
531 goto out; 531 goto out;
532 532
533 error = permission(nd.dentry->d_inode,MAY_EXEC,&nd); 533 error = vfs_permission(&nd, MAY_EXEC);
534 if (error) 534 if (error)
535 goto dput_and_out; 535 goto dput_and_out;
536 536
@@ -581,7 +581,7 @@ asmlinkage long sys_chroot(const char __user * filename)
581 if (error) 581 if (error)
582 goto out; 582 goto out;
583 583
584 error = permission(nd.dentry->d_inode,MAY_EXEC,&nd); 584 error = vfs_permission(&nd, MAY_EXEC);
585 if (error) 585 if (error)
586 goto dput_and_out; 586 goto dput_and_out;
587 587
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 1b5f502a4b8f..c3b8c1dc7cdf 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -874,6 +874,7 @@ static inline void unlock_super(struct super_block * sb)
874/* 874/*
875 * VFS helper functions.. 875 * VFS helper functions..
876 */ 876 */
877extern int vfs_permission(struct nameidata *, int);
877extern int vfs_create(struct inode *, struct dentry *, int, struct nameidata *); 878extern int vfs_create(struct inode *, struct dentry *, int, struct nameidata *);
878extern int vfs_mkdir(struct inode *, struct dentry *, int); 879extern int vfs_mkdir(struct inode *, struct dentry *, int);
879extern int vfs_mknod(struct inode *, struct dentry *, int, dev_t); 880extern int vfs_mknod(struct inode *, struct dentry *, int, dev_t);
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
index 41feca3bef86..acc73ba8bade 100644
--- a/net/unix/af_unix.c
+++ b/net/unix/af_unix.c
@@ -676,7 +676,7 @@ static struct sock *unix_find_other(struct sockaddr_un *sunname, int len,
676 err = path_lookup(sunname->sun_path, LOOKUP_FOLLOW, &nd); 676 err = path_lookup(sunname->sun_path, LOOKUP_FOLLOW, &nd);
677 if (err) 677 if (err)
678 goto fail; 678 goto fail;
679 err = permission(nd.dentry->d_inode,MAY_WRITE, &nd); 679 err = vfs_permission(&nd, MAY_WRITE);
680 if (err) 680 if (err)
681 goto put_fail; 681 goto put_fail;
682 682