summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@lst.de>2005-11-09 06:35:04 +0100
committerLinus Torvalds <torvalds@g5.osdl.org>2005-11-09 16:55:59 +0100
commit8c744fb83da0771afa04695028e3550b798dad90 (patch)
tree670896a1c2594965099853a6c992907abb3a886f
parent[PATCH] add a vfs_permission helper (diff)
downloadlinux-8c744fb83da0771afa04695028e3550b798dad90.tar.xz
linux-8c744fb83da0771afa04695028e3550b798dad90.zip
[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.c3
-rw-r--r--fs/binfmt_misc.c2
-rw-r--r--fs/exec.c2
-rw-r--r--fs/namei.c18
-rw-r--r--fs/ncpfs/ioctl.c34
-rw-r--r--fs/open.c2
-rw-r--r--fs/udf/file.c2
-rw-r--r--include/linux/fs.h5
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)
/* Allow ioctls if we have write-permissions even if read-only open.
* Needed so that programs such as fdrawcmd still can work on write
* protected disks */
- if (filp->f_mode & 2
- || permission(filp->f_dentry->d_inode, 2, NULL) == 0)
+ if ((filp->f_mode & FMODE_WRITE) || !file_permission(filp, MAY_WRITE))
filp->private_data = (void *)8;
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)
/* if the binary is not readable than enforce mm->dumpable=0
regardless of the interpreter's permissions */
- if (permission(bprm->file->f_dentry->d_inode, MAY_READ, NULL))
+ if (file_permission(bprm->file, MAY_READ))
bprm->interp_flags |= BINPRM_FLAGS_ENFORCE_NONDUMP;
allow_write_access(bprm->file);
diff --git a/fs/exec.c b/fs/exec.c
index 7bbb781b9ac6..c466fec5de20 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -896,7 +896,7 @@ int flush_old_exec(struct linux_binprm * bprm)
flush_thread();
if (bprm->e_uid != current->euid || bprm->e_gid != current->egid ||
- permission(bprm->file->f_dentry->d_inode,MAY_READ, NULL) ||
+ file_permission(bprm->file, MAY_READ) ||
(bprm->interp_flags & BINPRM_FLAGS_ENFORCE_NONDUMP)) {
suid_keys(current);
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)
return permission(nd->dentry->d_inode, mask, nd);
}
+/**
+ * file_permission - check for additional access rights to a given file
+ * @file: file to check access rights for
+ * @mask: right to check for (%MAY_READ, %MAY_WRITE, %MAY_EXEC)
+ *
+ * Used to check for read/write/execute permissions on an already opened
+ * file.
+ *
+ * Note:
+ * Do not use this function in new code. All access checks should
+ * be done using vfs_permission().
+ */
+int file_permission(struct file *file, int mask)
+{
+ return permission(file->f_dentry->d_inode, mask, NULL);
+}
+
/*
* get_write_access() gets write permission for a file.
* put_write_access() releases this write permission.
@@ -2551,6 +2568,7 @@ EXPORT_SYMBOL(path_release);
EXPORT_SYMBOL(path_walk);
EXPORT_SYMBOL(permission);
EXPORT_SYMBOL(vfs_permission);
+EXPORT_SYMBOL(file_permission);
EXPORT_SYMBOL(unlock_rename);
EXPORT_SYMBOL(vfs_create);
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 @@
#define NCP_PACKET_SIZE_INTERNAL 65536
static int
-ncp_get_fs_info(struct ncp_server* server, struct inode* inode, struct ncp_fs_info __user *arg)
+ncp_get_fs_info(struct ncp_server * server, struct file *file,
+ struct ncp_fs_info __user *arg)
{
+ struct inode *inode = file->f_dentry->d_inode;
struct ncp_fs_info info;
- if ((permission(inode, MAY_WRITE, NULL) != 0)
+ if ((file_permission(file, MAY_WRITE) != 0)
&& (current->uid != server->m.mounted_uid)) {
return -EACCES;
}
@@ -58,11 +60,13 @@ ncp_get_fs_info(struct ncp_server* server, struct inode* inode, struct ncp_fs_in
}
static int
-ncp_get_fs_info_v2(struct ncp_server* server, struct inode* inode, struct ncp_fs_info_v2 __user * arg)
+ncp_get_fs_info_v2(struct ncp_server * server, struct file *file,
+ struct ncp_fs_info_v2 __user * arg)
{
+ struct inode *inode = file->f_dentry->d_inode;
struct ncp_fs_info_v2 info2;
- if ((permission(inode, MAY_WRITE, NULL) != 0)
+ if ((file_permission(file, MAY_WRITE) != 0)
&& (current->uid != server->m.mounted_uid)) {
return -EACCES;
}
@@ -190,7 +194,7 @@ int ncp_ioctl(struct inode *inode, struct file *filp,
switch (cmd) {
case NCP_IOC_NCPREQUEST:
- if ((permission(inode, MAY_WRITE, NULL) != 0)
+ if ((file_permission(filp, MAY_WRITE) != 0)
&& (current->uid != server->m.mounted_uid)) {
return -EACCES;
}
@@ -245,16 +249,16 @@ int ncp_ioctl(struct inode *inode, struct file *filp,
return ncp_conn_logged_in(inode->i_sb);
case NCP_IOC_GET_FS_INFO:
- return ncp_get_fs_info(server, inode, argp);
+ return ncp_get_fs_info(server, filp, argp);
case NCP_IOC_GET_FS_INFO_V2:
- return ncp_get_fs_info_v2(server, inode, argp);
+ return ncp_get_fs_info_v2(server, filp, argp);
case NCP_IOC_GETMOUNTUID2:
{
unsigned long tmp = server->m.mounted_uid;
- if ( (permission(inode, MAY_READ, NULL) != 0)
+ if ((file_permission(filp, MAY_READ) != 0)
&& (current->uid != server->m.mounted_uid))
{
return -EACCES;
@@ -268,7 +272,7 @@ int ncp_ioctl(struct inode *inode, struct file *filp,
{
struct ncp_setroot_ioctl sr;
- if ( (permission(inode, MAY_READ, NULL) != 0)
+ if ((file_permission(filp, MAY_READ) != 0)
&& (current->uid != server->m.mounted_uid))
{
return -EACCES;
@@ -343,7 +347,7 @@ int ncp_ioctl(struct inode *inode, struct file *filp,
#ifdef CONFIG_NCPFS_PACKET_SIGNING
case NCP_IOC_SIGN_INIT:
- if ((permission(inode, MAY_WRITE, NULL) != 0)
+ if ((file_permission(filp, MAY_WRITE) != 0)
&& (current->uid != server->m.mounted_uid))
{
return -EACCES;
@@ -366,7 +370,7 @@ int ncp_ioctl(struct inode *inode, struct file *filp,
return 0;
case NCP_IOC_SIGN_WANTED:
- if ( (permission(inode, MAY_READ, NULL) != 0)
+ if ((file_permission(filp, MAY_READ) != 0)
&& (current->uid != server->m.mounted_uid))
{
return -EACCES;
@@ -379,7 +383,7 @@ int ncp_ioctl(struct inode *inode, struct file *filp,
{
int newstate;
- if ( (permission(inode, MAY_WRITE, NULL) != 0)
+ if ((file_permission(filp, MAY_WRITE) != 0)
&& (current->uid != server->m.mounted_uid))
{
return -EACCES;
@@ -400,7 +404,7 @@ int ncp_ioctl(struct inode *inode, struct file *filp,
#ifdef CONFIG_NCPFS_IOCTL_LOCKING
case NCP_IOC_LOCKUNLOCK:
- if ( (permission(inode, MAY_WRITE, NULL) != 0)
+ if ((file_permission(filp, MAY_WRITE) != 0)
&& (current->uid != server->m.mounted_uid))
{
return -EACCES;
@@ -605,7 +609,7 @@ outrel:
#endif /* CONFIG_NCPFS_NLS */
case NCP_IOC_SETDENTRYTTL:
- if ((permission(inode, MAY_WRITE, NULL) != 0) &&
+ if ((file_permission(filp, MAY_WRITE) != 0) &&
(current->uid != server->m.mounted_uid))
return -EACCES;
{
@@ -635,7 +639,7 @@ outrel:
so we have this out of switch */
if (cmd == NCP_IOC_GETMOUNTUID) {
__kernel_uid_t uid = 0;
- if ((permission(inode, MAY_READ, NULL) != 0)
+ if ((file_permission(filp, MAY_READ) != 0)
&& (current->uid != server->m.mounted_uid)) {
return -EACCES;
}
diff --git a/fs/open.c b/fs/open.c
index baffc084580d..f53a5b9ffb7d 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -563,7 +563,7 @@ asmlinkage long sys_fchdir(unsigned int fd)
if (!S_ISDIR(inode->i_mode))
goto out_putf;
- error = permission(inode, MAY_EXEC, NULL);
+ error = file_permission(file, MAY_EXEC);
if (!error)
set_fs_pwd(current->fs, mnt, dentry);
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,
{
int result = -EINVAL;
- if ( permission(inode, MAY_READ, NULL) != 0 )
+ if ( file_permission(filp, MAY_READ) != 0 )
{
udf_debug("no permission to access inode %lu\n",
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
extern void dentry_unhash(struct dentry *dentry);
/*
+ * VFS file helper functions.
+ */
+extern int file_permission(struct file *, int);
+
+/*
* File types
*
* NOTE! These match bits 12..15 of stat.st_mode