add a file_permission helper
Subsystems (5)
PATCH 2/2 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 <[email protected]>
drivers/block/floppy.c +1 -2
@@ -3770,8 +3770,7 @@/* 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 )
fs/binfmt_misc.c +1 -1
@@ -150,7 +150,7 @@/* 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);
fs/exec.c +1 -1
@@ -891,7 +891,7 @@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;
include/linux/fs.h +5 -0
@@ -878,6 +878,11 @@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
fs/ncpfs/ioctl.c +19 -15
@@ -30,11 +30,13 @@#define NCP_PACKET_SIZE_INTERNAL 65536static 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 @@ }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 @@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 @@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 @@ {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 @@#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 @@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 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 @@#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 @@#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 @@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 ; }
fs/open.c +1 -1
@@ -559,7 +559,7 @@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:
fs/udf/file.c +1 -1
@@ -186,7 +186,7 @@ {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);
fs/namei.c +18 -0
@@ -271,6 +271,23 @@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_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);
Thank you for these updated/new file_permission and vfs_permission: us stackable file system developers have often needed more standalone and/or reentrant vfs_* functions to call.
Erez.