Commit 8c744fb8 authored by Christoph Hellwig's avatar Christoph Hellwig Committed by Linus Torvalds

[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: default avatarChristoph Hellwig <hch@lst.de>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent e4543edd
...@@ -3776,8 +3776,7 @@ static int floppy_open(struct inode *inode, struct file *filp) ...@@ -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. /* Allow ioctls if we have write-permissions even if read-only open.
* Needed so that programs such as fdrawcmd still can work on write * Needed so that programs such as fdrawcmd still can work on write
* protected disks */ * protected disks */
if (filp->f_mode & 2 if ((filp->f_mode & FMODE_WRITE) || !file_permission(filp, MAY_WRITE))
|| permission(filp->f_dentry->d_inode, 2, NULL) == 0)
filp->private_data = (void *)8; filp->private_data = (void *)8;
if (UFDCS->rawcmd == 1) if (UFDCS->rawcmd == 1)
......
...@@ -150,7 +150,7 @@ static int load_misc_binary(struct linux_binprm *bprm, struct pt_regs *regs) ...@@ -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 /* if the binary is not readable than enforce mm->dumpable=0
regardless of the interpreter's permissions */ 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; bprm->interp_flags |= BINPRM_FLAGS_ENFORCE_NONDUMP;
allow_write_access(bprm->file); allow_write_access(bprm->file);
......
...@@ -896,7 +896,7 @@ int flush_old_exec(struct linux_binprm * bprm) ...@@ -896,7 +896,7 @@ int flush_old_exec(struct linux_binprm * bprm)
flush_thread(); flush_thread();
if (bprm->e_uid != current->euid || bprm->e_gid != current->egid || 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)) { (bprm->interp_flags & BINPRM_FLAGS_ENFORCE_NONDUMP)) {
suid_keys(current); suid_keys(current);
current->mm->dumpable = suid_dumpable; current->mm->dumpable = suid_dumpable;
......
...@@ -271,6 +271,23 @@ int vfs_permission(struct nameidata *nd, int mask) ...@@ -271,6 +271,23 @@ int vfs_permission(struct nameidata *nd, int mask)
return permission(nd->dentry->d_inode, mask, nd); 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. * get_write_access() gets write permission for a file.
* put_write_access() releases this write permission. * put_write_access() releases this write permission.
...@@ -2551,6 +2568,7 @@ EXPORT_SYMBOL(path_release); ...@@ -2551,6 +2568,7 @@ EXPORT_SYMBOL(path_release);
EXPORT_SYMBOL(path_walk); EXPORT_SYMBOL(path_walk);
EXPORT_SYMBOL(permission); EXPORT_SYMBOL(permission);
EXPORT_SYMBOL(vfs_permission); EXPORT_SYMBOL(vfs_permission);
EXPORT_SYMBOL(file_permission);
EXPORT_SYMBOL(unlock_rename); EXPORT_SYMBOL(unlock_rename);
EXPORT_SYMBOL(vfs_create); EXPORT_SYMBOL(vfs_create);
EXPORT_SYMBOL(vfs_follow_link); EXPORT_SYMBOL(vfs_follow_link);
......
...@@ -30,11 +30,13 @@ ...@@ -30,11 +30,13 @@
#define NCP_PACKET_SIZE_INTERNAL 65536 #define NCP_PACKET_SIZE_INTERNAL 65536
static int 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; 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)) { && (current->uid != server->m.mounted_uid)) {
return -EACCES; return -EACCES;
} }
...@@ -58,11 +60,13 @@ ncp_get_fs_info(struct ncp_server* server, struct inode* inode, struct ncp_fs_in ...@@ -58,11 +60,13 @@ ncp_get_fs_info(struct ncp_server* server, struct inode* inode, struct ncp_fs_in
} }
static int 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; 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)) { && (current->uid != server->m.mounted_uid)) {
return -EACCES; return -EACCES;
} }
...@@ -190,7 +194,7 @@ int ncp_ioctl(struct inode *inode, struct file *filp, ...@@ -190,7 +194,7 @@ int ncp_ioctl(struct inode *inode, struct file *filp,
switch (cmd) { switch (cmd) {
case NCP_IOC_NCPREQUEST: case NCP_IOC_NCPREQUEST:
if ((permission(inode, MAY_WRITE, NULL) != 0) if ((file_permission(filp, MAY_WRITE) != 0)
&& (current->uid != server->m.mounted_uid)) { && (current->uid != server->m.mounted_uid)) {
return -EACCES; return -EACCES;
} }
...@@ -245,16 +249,16 @@ int ncp_ioctl(struct inode *inode, struct file *filp, ...@@ -245,16 +249,16 @@ int ncp_ioctl(struct inode *inode, struct file *filp,
return ncp_conn_logged_in(inode->i_sb); return ncp_conn_logged_in(inode->i_sb);
case NCP_IOC_GET_FS_INFO: 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: 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: case NCP_IOC_GETMOUNTUID2:
{ {
unsigned long tmp = server->m.mounted_uid; 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)) && (current->uid != server->m.mounted_uid))
{ {
return -EACCES; return -EACCES;
...@@ -268,7 +272,7 @@ int ncp_ioctl(struct inode *inode, struct file *filp, ...@@ -268,7 +272,7 @@ int ncp_ioctl(struct inode *inode, struct file *filp,
{ {
struct ncp_setroot_ioctl sr; 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)) && (current->uid != server->m.mounted_uid))
{ {
return -EACCES; return -EACCES;
...@@ -343,7 +347,7 @@ int ncp_ioctl(struct inode *inode, struct file *filp, ...@@ -343,7 +347,7 @@ int ncp_ioctl(struct inode *inode, struct file *filp,
#ifdef CONFIG_NCPFS_PACKET_SIGNING #ifdef CONFIG_NCPFS_PACKET_SIGNING
case NCP_IOC_SIGN_INIT: 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)) && (current->uid != server->m.mounted_uid))
{ {
return -EACCES; return -EACCES;
...@@ -366,7 +370,7 @@ int ncp_ioctl(struct inode *inode, struct file *filp, ...@@ -366,7 +370,7 @@ int ncp_ioctl(struct inode *inode, struct file *filp,
return 0; return 0;
case NCP_IOC_SIGN_WANTED: 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)) && (current->uid != server->m.mounted_uid))
{ {
return -EACCES; return -EACCES;
...@@ -379,7 +383,7 @@ int ncp_ioctl(struct inode *inode, struct file *filp, ...@@ -379,7 +383,7 @@ int ncp_ioctl(struct inode *inode, struct file *filp,
{ {
int newstate; int newstate;
if ( (permission(inode, MAY_WRITE, NULL) != 0) if ((file_permission(filp, MAY_WRITE) != 0)
&& (current->uid != server->m.mounted_uid)) && (current->uid != server->m.mounted_uid))
{ {
return -EACCES; return -EACCES;
...@@ -400,7 +404,7 @@ int ncp_ioctl(struct inode *inode, struct file *filp, ...@@ -400,7 +404,7 @@ int ncp_ioctl(struct inode *inode, struct file *filp,
#ifdef CONFIG_NCPFS_IOCTL_LOCKING #ifdef CONFIG_NCPFS_IOCTL_LOCKING
case NCP_IOC_LOCKUNLOCK: case NCP_IOC_LOCKUNLOCK:
if ( (permission(inode, MAY_WRITE, NULL) != 0) if ((file_permission(filp, MAY_WRITE) != 0)
&& (current->uid != server->m.mounted_uid)) && (current->uid != server->m.mounted_uid))
{ {
return -EACCES; return -EACCES;
...@@ -605,7 +609,7 @@ outrel: ...@@ -605,7 +609,7 @@ outrel:
#endif /* CONFIG_NCPFS_NLS */ #endif /* CONFIG_NCPFS_NLS */
case NCP_IOC_SETDENTRYTTL: case NCP_IOC_SETDENTRYTTL:
if ((permission(inode, MAY_WRITE, NULL) != 0) && if ((file_permission(filp, MAY_WRITE) != 0) &&
(current->uid != server->m.mounted_uid)) (current->uid != server->m.mounted_uid))
return -EACCES; return -EACCES;
{ {
...@@ -635,7 +639,7 @@ outrel: ...@@ -635,7 +639,7 @@ outrel:
so we have this out of switch */ so we have this out of switch */
if (cmd == NCP_IOC_GETMOUNTUID) { if (cmd == NCP_IOC_GETMOUNTUID) {
__kernel_uid_t uid = 0; __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)) { && (current->uid != server->m.mounted_uid)) {
return -EACCES; return -EACCES;
} }
......
...@@ -563,7 +563,7 @@ asmlinkage long sys_fchdir(unsigned int fd) ...@@ -563,7 +563,7 @@ asmlinkage long sys_fchdir(unsigned int fd)
if (!S_ISDIR(inode->i_mode)) if (!S_ISDIR(inode->i_mode))
goto out_putf; goto out_putf;
error = permission(inode, MAY_EXEC, NULL); error = file_permission(file, MAY_EXEC);
if (!error) if (!error)
set_fs_pwd(current->fs, mnt, dentry); set_fs_pwd(current->fs, mnt, dentry);
out_putf: out_putf:
......
...@@ -186,7 +186,7 @@ int udf_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, ...@@ -186,7 +186,7 @@ int udf_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
{ {
int result = -EINVAL; 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", udf_debug("no permission to access inode %lu\n",
inode->i_ino); inode->i_ino);
......
...@@ -889,6 +889,11 @@ extern int vfs_rename(struct inode *, struct dentry *, struct inode *, struct de ...@@ -889,6 +889,11 @@ extern int vfs_rename(struct inode *, struct dentry *, struct inode *, struct de
*/ */
extern void dentry_unhash(struct dentry *dentry); extern void dentry_unhash(struct dentry *dentry);
/*
* VFS file helper functions.
*/
extern int file_permission(struct file *, int);
/* /*
* File types * File types
* *
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment