Commit 745ca247 authored by David Howells's avatar David Howells Committed by James Morris

CRED: Pass credentials through dentry_open()

Pass credentials through dentry_open() so that the COW creds patch can have
SELinux's flush_unauthorized_files() pass the appropriate creds back to itself
when it opens its null chardev.

The security_dentry_open() call also now takes a creds pointer, as does the
dentry_open hook in struct security_operations.
Signed-off-by: default avatarDavid Howells <dhowells@redhat.com>
Acked-by: default avatarJames Morris <jmorris@namei.org>
Signed-off-by: default avatarJames Morris <jmorris@namei.org>
parent 88e67f3b
...@@ -323,7 +323,7 @@ static int spufs_context_open(struct dentry *dentry, struct vfsmount *mnt) ...@@ -323,7 +323,7 @@ static int spufs_context_open(struct dentry *dentry, struct vfsmount *mnt)
goto out; goto out;
} }
filp = dentry_open(dentry, mnt, O_RDONLY); filp = dentry_open(dentry, mnt, O_RDONLY, current_cred());
if (IS_ERR(filp)) { if (IS_ERR(filp)) {
put_unused_fd(ret); put_unused_fd(ret);
ret = PTR_ERR(filp); ret = PTR_ERR(filp);
...@@ -562,7 +562,7 @@ static int spufs_gang_open(struct dentry *dentry, struct vfsmount *mnt) ...@@ -562,7 +562,7 @@ static int spufs_gang_open(struct dentry *dentry, struct vfsmount *mnt)
goto out; goto out;
} }
filp = dentry_open(dentry, mnt, O_RDONLY); filp = dentry_open(dentry, mnt, O_RDONLY, current_cred());
if (IS_ERR(filp)) { if (IS_ERR(filp)) {
put_unused_fd(ret); put_unused_fd(ret);
ret = PTR_ERR(filp); ret = PTR_ERR(filp);
......
...@@ -159,7 +159,8 @@ void mconsole_proc(struct mc_request *req) ...@@ -159,7 +159,8 @@ void mconsole_proc(struct mc_request *req)
goto out_kill; goto out_kill;
} }
file = dentry_open(nd.path.dentry, nd.path.mnt, O_RDONLY); file = dentry_open(nd.path.dentry, nd.path.mnt, O_RDONLY,
current_cred());
if (IS_ERR(file)) { if (IS_ERR(file)) {
mconsole_reply(req, "Failed to open file", 1, 0); mconsole_reply(req, "Failed to open file", 1, 0);
goto out_kill; goto out_kill;
......
...@@ -307,7 +307,8 @@ static int autofs_dev_ioctl_open_mountpoint(const char *path, dev_t devid) ...@@ -307,7 +307,8 @@ static int autofs_dev_ioctl_open_mountpoint(const char *path, dev_t devid)
goto out; goto out;
} }
filp = dentry_open(nd.path.dentry, nd.path.mnt, O_RDONLY); filp = dentry_open(nd.path.dentry, nd.path.mnt, O_RDONLY,
current_cred());
if (IS_ERR(filp)) { if (IS_ERR(filp)) {
err = PTR_ERR(filp); err = PTR_ERR(filp);
goto out; goto out;
......
...@@ -691,7 +691,8 @@ int ecryptfs_init_kthread(void); ...@@ -691,7 +691,8 @@ int ecryptfs_init_kthread(void);
void ecryptfs_destroy_kthread(void); void ecryptfs_destroy_kthread(void);
int ecryptfs_privileged_open(struct file **lower_file, int ecryptfs_privileged_open(struct file **lower_file,
struct dentry *lower_dentry, struct dentry *lower_dentry,
struct vfsmount *lower_mnt); struct vfsmount *lower_mnt,
const struct cred *cred);
int ecryptfs_init_persistent_file(struct dentry *ecryptfs_dentry); int ecryptfs_init_persistent_file(struct dentry *ecryptfs_dentry);
#endif /* #ifndef ECRYPTFS_KERNEL_H */ #endif /* #ifndef ECRYPTFS_KERNEL_H */
...@@ -73,7 +73,7 @@ static int ecryptfs_threadfn(void *ignored) ...@@ -73,7 +73,7 @@ static int ecryptfs_threadfn(void *ignored)
mntget(req->lower_mnt); mntget(req->lower_mnt);
(*req->lower_file) = dentry_open( (*req->lower_file) = dentry_open(
req->lower_dentry, req->lower_mnt, req->lower_dentry, req->lower_mnt,
(O_RDWR | O_LARGEFILE)); (O_RDWR | O_LARGEFILE), current_cred());
req->flags |= ECRYPTFS_REQ_PROCESSED; req->flags |= ECRYPTFS_REQ_PROCESSED;
} }
wake_up(&req->wait); wake_up(&req->wait);
...@@ -132,7 +132,8 @@ void ecryptfs_destroy_kthread(void) ...@@ -132,7 +132,8 @@ void ecryptfs_destroy_kthread(void)
*/ */
int ecryptfs_privileged_open(struct file **lower_file, int ecryptfs_privileged_open(struct file **lower_file,
struct dentry *lower_dentry, struct dentry *lower_dentry,
struct vfsmount *lower_mnt) struct vfsmount *lower_mnt,
const struct cred *cred)
{ {
struct ecryptfs_open_req *req; struct ecryptfs_open_req *req;
int rc = 0; int rc = 0;
...@@ -143,7 +144,7 @@ int ecryptfs_privileged_open(struct file **lower_file, ...@@ -143,7 +144,7 @@ int ecryptfs_privileged_open(struct file **lower_file,
dget(lower_dentry); dget(lower_dentry);
mntget(lower_mnt); mntget(lower_mnt);
(*lower_file) = dentry_open(lower_dentry, lower_mnt, (*lower_file) = dentry_open(lower_dentry, lower_mnt,
(O_RDWR | O_LARGEFILE)); (O_RDWR | O_LARGEFILE), cred);
if (!IS_ERR(*lower_file)) if (!IS_ERR(*lower_file))
goto out; goto out;
req = kmem_cache_alloc(ecryptfs_open_req_cache, GFP_KERNEL); req = kmem_cache_alloc(ecryptfs_open_req_cache, GFP_KERNEL);
...@@ -184,7 +185,7 @@ int ecryptfs_privileged_open(struct file **lower_file, ...@@ -184,7 +185,7 @@ int ecryptfs_privileged_open(struct file **lower_file,
dget(lower_dentry); dget(lower_dentry);
mntget(lower_mnt); mntget(lower_mnt);
(*lower_file) = dentry_open(lower_dentry, lower_mnt, (*lower_file) = dentry_open(lower_dentry, lower_mnt,
(O_RDONLY | O_LARGEFILE)); (O_RDONLY | O_LARGEFILE), cred);
if (IS_ERR(*lower_file)) { if (IS_ERR(*lower_file)) {
rc = PTR_ERR(*req->lower_file); rc = PTR_ERR(*req->lower_file);
(*lower_file) = NULL; (*lower_file) = NULL;
......
...@@ -115,6 +115,7 @@ void __ecryptfs_printk(const char *fmt, ...) ...@@ -115,6 +115,7 @@ void __ecryptfs_printk(const char *fmt, ...)
*/ */
int ecryptfs_init_persistent_file(struct dentry *ecryptfs_dentry) int ecryptfs_init_persistent_file(struct dentry *ecryptfs_dentry)
{ {
const struct cred *cred = current_cred();
struct ecryptfs_inode_info *inode_info = struct ecryptfs_inode_info *inode_info =
ecryptfs_inode_to_private(ecryptfs_dentry->d_inode); ecryptfs_inode_to_private(ecryptfs_dentry->d_inode);
int rc = 0; int rc = 0;
...@@ -127,7 +128,7 @@ int ecryptfs_init_persistent_file(struct dentry *ecryptfs_dentry) ...@@ -127,7 +128,7 @@ int ecryptfs_init_persistent_file(struct dentry *ecryptfs_dentry)
lower_dentry = ecryptfs_dentry_to_lower(ecryptfs_dentry); lower_dentry = ecryptfs_dentry_to_lower(ecryptfs_dentry);
rc = ecryptfs_privileged_open(&inode_info->lower_file, rc = ecryptfs_privileged_open(&inode_info->lower_file,
lower_dentry, lower_mnt); lower_dentry, lower_mnt, cred);
if (rc || IS_ERR(inode_info->lower_file)) { if (rc || IS_ERR(inode_info->lower_file)) {
printk(KERN_ERR "Error opening lower persistent file " printk(KERN_ERR "Error opening lower persistent file "
"for lower_dentry [0x%p] and lower_mnt [0x%p]; " "for lower_dentry [0x%p] and lower_mnt [0x%p]; "
......
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
#include <linux/module.h> #include <linux/module.h>
#include <linux/mount.h> #include <linux/mount.h>
#include <linux/namei.h> #include <linux/namei.h>
#include <linux/sched.h>
#define dprintk(fmt, args...) do{}while(0) #define dprintk(fmt, args...) do{}while(0)
...@@ -249,6 +250,7 @@ static int filldir_one(void * __buf, const char * name, int len, ...@@ -249,6 +250,7 @@ static int filldir_one(void * __buf, const char * name, int len,
static int get_name(struct vfsmount *mnt, struct dentry *dentry, static int get_name(struct vfsmount *mnt, struct dentry *dentry,
char *name, struct dentry *child) char *name, struct dentry *child)
{ {
const struct cred *cred = current_cred();
struct inode *dir = dentry->d_inode; struct inode *dir = dentry->d_inode;
int error; int error;
struct file *file; struct file *file;
...@@ -263,7 +265,7 @@ static int get_name(struct vfsmount *mnt, struct dentry *dentry, ...@@ -263,7 +265,7 @@ static int get_name(struct vfsmount *mnt, struct dentry *dentry,
/* /*
* Open the directory ... * Open the directory ...
*/ */
file = dentry_open(dget(dentry), mntget(mnt), O_RDONLY); file = dentry_open(dget(dentry), mntget(mnt), O_RDONLY, cred);
error = PTR_ERR(file); error = PTR_ERR(file);
if (IS_ERR(file)) if (IS_ERR(file))
goto out; goto out;
......
...@@ -426,6 +426,7 @@ static int file_mode(int fmode) ...@@ -426,6 +426,7 @@ static int file_mode(int fmode)
static int hppfs_open(struct inode *inode, struct file *file) static int hppfs_open(struct inode *inode, struct file *file)
{ {
const struct cred *cred = current_cred();
struct hppfs_private *data; struct hppfs_private *data;
struct vfsmount *proc_mnt; struct vfsmount *proc_mnt;
struct dentry *proc_dentry; struct dentry *proc_dentry;
...@@ -446,7 +447,7 @@ static int hppfs_open(struct inode *inode, struct file *file) ...@@ -446,7 +447,7 @@ static int hppfs_open(struct inode *inode, struct file *file)
/* XXX This isn't closed anywhere */ /* XXX This isn't closed anywhere */
data->proc_file = dentry_open(dget(proc_dentry), mntget(proc_mnt), data->proc_file = dentry_open(dget(proc_dentry), mntget(proc_mnt),
file_mode(file->f_mode)); file_mode(file->f_mode), cred);
err = PTR_ERR(data->proc_file); err = PTR_ERR(data->proc_file);
if (IS_ERR(data->proc_file)) if (IS_ERR(data->proc_file))
goto out_free1; goto out_free1;
...@@ -489,6 +490,7 @@ static int hppfs_open(struct inode *inode, struct file *file) ...@@ -489,6 +490,7 @@ static int hppfs_open(struct inode *inode, struct file *file)
static int hppfs_dir_open(struct inode *inode, struct file *file) static int hppfs_dir_open(struct inode *inode, struct file *file)
{ {
const struct cred *cred = current_cred();
struct hppfs_private *data; struct hppfs_private *data;
struct vfsmount *proc_mnt; struct vfsmount *proc_mnt;
struct dentry *proc_dentry; struct dentry *proc_dentry;
...@@ -502,7 +504,7 @@ static int hppfs_dir_open(struct inode *inode, struct file *file) ...@@ -502,7 +504,7 @@ static int hppfs_dir_open(struct inode *inode, struct file *file)
proc_dentry = HPPFS_I(inode)->proc_dentry; proc_dentry = HPPFS_I(inode)->proc_dentry;
proc_mnt = inode->i_sb->s_fs_info; proc_mnt = inode->i_sb->s_fs_info;
data->proc_file = dentry_open(dget(proc_dentry), mntget(proc_mnt), data->proc_file = dentry_open(dget(proc_dentry), mntget(proc_mnt),
file_mode(file->f_mode)); file_mode(file->f_mode), cred);
err = PTR_ERR(data->proc_file); err = PTR_ERR(data->proc_file);
if (IS_ERR(data->proc_file)) if (IS_ERR(data->proc_file))
goto out_free; goto out_free;
......
...@@ -41,7 +41,8 @@ static struct file *do_open(char *name, int flags) ...@@ -41,7 +41,8 @@ static struct file *do_open(char *name, int flags)
error = may_open(&nd, MAY_WRITE, FMODE_WRITE); error = may_open(&nd, MAY_WRITE, FMODE_WRITE);
if (!error) if (!error)
return dentry_open(nd.path.dentry, nd.path.mnt, flags); return dentry_open(nd.path.dentry, nd.path.mnt, flags,
current_cred());
path_put(&nd.path); path_put(&nd.path);
return ERR_PTR(error); return ERR_PTR(error);
......
...@@ -226,7 +226,8 @@ nfsd4_list_rec_dir(struct dentry *dir, recdir_func *f) ...@@ -226,7 +226,8 @@ nfsd4_list_rec_dir(struct dentry *dir, recdir_func *f)
nfs4_save_user(&uid, &gid); nfs4_save_user(&uid, &gid);
filp = dentry_open(dget(dir), mntget(rec_dir.mnt), O_RDONLY); filp = dentry_open(dget(dir), mntget(rec_dir.mnt), O_RDONLY,
current_cred());
status = PTR_ERR(filp); status = PTR_ERR(filp);
if (IS_ERR(filp)) if (IS_ERR(filp))
goto out; goto out;
......
...@@ -671,6 +671,7 @@ __be32 ...@@ -671,6 +671,7 @@ __be32
nfsd_open(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, nfsd_open(struct svc_rqst *rqstp, struct svc_fh *fhp, int type,
int access, struct file **filp) int access, struct file **filp)
{ {
const struct cred *cred = current_cred();
struct dentry *dentry; struct dentry *dentry;
struct inode *inode; struct inode *inode;
int flags = O_RDONLY|O_LARGEFILE; int flags = O_RDONLY|O_LARGEFILE;
...@@ -725,7 +726,7 @@ nfsd_open(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, ...@@ -725,7 +726,7 @@ nfsd_open(struct svc_rqst *rqstp, struct svc_fh *fhp, int type,
DQUOT_INIT(inode); DQUOT_INIT(inode);
} }
*filp = dentry_open(dget(dentry), mntget(fhp->fh_export->ex_path.mnt), *filp = dentry_open(dget(dentry), mntget(fhp->fh_export->ex_path.mnt),
flags); flags, cred);
if (IS_ERR(*filp)) if (IS_ERR(*filp))
host_err = PTR_ERR(*filp); host_err = PTR_ERR(*filp);
out_nfserr: out_nfserr:
......
...@@ -783,7 +783,8 @@ static inline int __get_file_write_access(struct inode *inode, ...@@ -783,7 +783,8 @@ static inline int __get_file_write_access(struct inode *inode,
static struct file *__dentry_open(struct dentry *dentry, struct vfsmount *mnt, static struct file *__dentry_open(struct dentry *dentry, struct vfsmount *mnt,
int flags, struct file *f, int flags, struct file *f,
int (*open)(struct inode *, struct file *)) int (*open)(struct inode *, struct file *),
const struct cred *cred)
{ {
struct inode *inode; struct inode *inode;
int error; int error;
...@@ -807,7 +808,7 @@ static struct file *__dentry_open(struct dentry *dentry, struct vfsmount *mnt, ...@@ -807,7 +808,7 @@ static struct file *__dentry_open(struct dentry *dentry, struct vfsmount *mnt,
f->f_op = fops_get(inode->i_fop); f->f_op = fops_get(inode->i_fop);
file_move(f, &inode->i_sb->s_files); file_move(f, &inode->i_sb->s_files);
error = security_dentry_open(f); error = security_dentry_open(f, cred);
if (error) if (error)
goto cleanup_all; goto cleanup_all;
...@@ -882,6 +883,8 @@ static struct file *__dentry_open(struct dentry *dentry, struct vfsmount *mnt, ...@@ -882,6 +883,8 @@ static struct file *__dentry_open(struct dentry *dentry, struct vfsmount *mnt,
struct file *lookup_instantiate_filp(struct nameidata *nd, struct dentry *dentry, struct file *lookup_instantiate_filp(struct nameidata *nd, struct dentry *dentry,
int (*open)(struct inode *, struct file *)) int (*open)(struct inode *, struct file *))
{ {
const struct cred *cred = current_cred();
if (IS_ERR(nd->intent.open.file)) if (IS_ERR(nd->intent.open.file))
goto out; goto out;
if (IS_ERR(dentry)) if (IS_ERR(dentry))
...@@ -889,7 +892,7 @@ struct file *lookup_instantiate_filp(struct nameidata *nd, struct dentry *dentry ...@@ -889,7 +892,7 @@ struct file *lookup_instantiate_filp(struct nameidata *nd, struct dentry *dentry
nd->intent.open.file = __dentry_open(dget(dentry), mntget(nd->path.mnt), nd->intent.open.file = __dentry_open(dget(dentry), mntget(nd->path.mnt),
nd->intent.open.flags - 1, nd->intent.open.flags - 1,
nd->intent.open.file, nd->intent.open.file,
open); open, cred);
out: out:
return nd->intent.open.file; return nd->intent.open.file;
out_err: out_err:
...@@ -908,6 +911,7 @@ EXPORT_SYMBOL_GPL(lookup_instantiate_filp); ...@@ -908,6 +911,7 @@ EXPORT_SYMBOL_GPL(lookup_instantiate_filp);
*/ */
struct file *nameidata_to_filp(struct nameidata *nd, int flags) struct file *nameidata_to_filp(struct nameidata *nd, int flags)
{ {
const struct cred *cred = current_cred();
struct file *filp; struct file *filp;
/* Pick up the filp from the open intent */ /* Pick up the filp from the open intent */
...@@ -915,7 +919,7 @@ struct file *nameidata_to_filp(struct nameidata *nd, int flags) ...@@ -915,7 +919,7 @@ struct file *nameidata_to_filp(struct nameidata *nd, int flags)
/* Has the filesystem initialised the file for us? */ /* Has the filesystem initialised the file for us? */
if (filp->f_path.dentry == NULL) if (filp->f_path.dentry == NULL)
filp = __dentry_open(nd->path.dentry, nd->path.mnt, flags, filp, filp = __dentry_open(nd->path.dentry, nd->path.mnt, flags, filp,
NULL); NULL, cred);
else else
path_put(&nd->path); path_put(&nd->path);
return filp; return filp;
...@@ -925,7 +929,8 @@ struct file *nameidata_to_filp(struct nameidata *nd, int flags) ...@@ -925,7 +929,8 @@ struct file *nameidata_to_filp(struct nameidata *nd, int flags)
* dentry_open() will have done dput(dentry) and mntput(mnt) if it returns an * dentry_open() will have done dput(dentry) and mntput(mnt) if it returns an
* error. * error.
*/ */
struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags) struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags,
const struct cred *cred)
{ {
int error; int error;
struct file *f; struct file *f;
...@@ -950,7 +955,7 @@ struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags) ...@@ -950,7 +955,7 @@ struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags)
return ERR_PTR(error); return ERR_PTR(error);
} }
return __dentry_open(dentry, mnt, flags, f, NULL); return __dentry_open(dentry, mnt, flags, f, NULL, cred);
} }
EXPORT_SYMBOL(dentry_open); EXPORT_SYMBOL(dentry_open);
......
...@@ -256,6 +256,7 @@ xfs_open_by_handle( ...@@ -256,6 +256,7 @@ xfs_open_by_handle(
struct file *parfilp, struct file *parfilp,
struct inode *parinode) struct inode *parinode)
{ {
const struct cred *cred = current_cred();
int error; int error;
int new_fd; int new_fd;
int permflag; int permflag;
...@@ -321,7 +322,7 @@ xfs_open_by_handle( ...@@ -321,7 +322,7 @@ xfs_open_by_handle(
mntget(parfilp->f_path.mnt); mntget(parfilp->f_path.mnt);
/* Create file pointer. */ /* Create file pointer. */
filp = dentry_open(dentry, parfilp->f_path.mnt, hreq.oflags); filp = dentry_open(dentry, parfilp->f_path.mnt, hreq.oflags, cred);
if (IS_ERR(filp)) { if (IS_ERR(filp)) {
put_unused_fd(new_fd); put_unused_fd(new_fd);
return -XFS_ERROR(-PTR_ERR(filp)); return -XFS_ERROR(-PTR_ERR(filp));
......
...@@ -315,6 +315,7 @@ struct poll_table_struct; ...@@ -315,6 +315,7 @@ struct poll_table_struct;
struct kstatfs; struct kstatfs;
struct vm_area_struct; struct vm_area_struct;
struct vfsmount; struct vfsmount;
struct cred;
extern void __init inode_init(void); extern void __init inode_init(void);
extern void __init inode_init_early(void); extern void __init inode_init_early(void);
...@@ -1673,7 +1674,8 @@ extern int do_truncate(struct dentry *, loff_t start, unsigned int time_attrs, ...@@ -1673,7 +1674,8 @@ extern int do_truncate(struct dentry *, loff_t start, unsigned int time_attrs,
extern long do_sys_open(int dfd, const char __user *filename, int flags, extern long do_sys_open(int dfd, const char __user *filename, int flags,
int mode); int mode);
extern struct file *filp_open(const char *, int, int); extern struct file *filp_open(const char *, int, int);
extern struct file * dentry_open(struct dentry *, struct vfsmount *, int); extern struct file * dentry_open(struct dentry *, struct vfsmount *, int,
const struct cred *);
extern int filp_close(struct file *, fl_owner_t id); extern int filp_close(struct file *, fl_owner_t id);
extern char * getname(const char __user *); extern char * getname(const char __user *);
......
...@@ -1402,7 +1402,7 @@ struct security_operations { ...@@ -1402,7 +1402,7 @@ struct security_operations {
int (*file_send_sigiotask) (struct task_struct *tsk, int (*file_send_sigiotask) (struct task_struct *tsk,
struct fown_struct *fown, int sig); struct fown_struct *fown, int sig);
int (*file_receive) (struct file *file); int (*file_receive) (struct file *file);
int (*dentry_open) (struct file *file); int (*dentry_open) (struct file *file, const struct cred *cred);
int (*task_create) (unsigned long clone_flags); int (*task_create) (unsigned long clone_flags);
int (*cred_alloc_security) (struct cred *cred); int (*cred_alloc_security) (struct cred *cred);
...@@ -1658,7 +1658,7 @@ int security_file_set_fowner(struct file *file); ...@@ -1658,7 +1658,7 @@ int security_file_set_fowner(struct file *file);
int security_file_send_sigiotask(struct task_struct *tsk, int security_file_send_sigiotask(struct task_struct *tsk,
struct fown_struct *fown, int sig); struct fown_struct *fown, int sig);
int security_file_receive(struct file *file); int security_file_receive(struct file *file);
int security_dentry_open(struct file *file); int security_dentry_open(struct file *file, const struct cred *cred);
int security_task_create(unsigned long clone_flags); int security_task_create(unsigned long clone_flags);
int security_cred_alloc(struct cred *cred); int security_cred_alloc(struct cred *cred);
void security_cred_free(struct cred *cred); void security_cred_free(struct cred *cred);
...@@ -2171,7 +2171,8 @@ static inline int security_file_receive(struct file *file) ...@@ -2171,7 +2171,8 @@ static inline int security_file_receive(struct file *file)
return 0; return 0;
} }
static inline int security_dentry_open(struct file *file) static inline int security_dentry_open(struct file *file,
const struct cred *cred)
{ {
return 0; return 0;
} }
......
...@@ -594,6 +594,7 @@ static int mq_attr_ok(struct mq_attr *attr) ...@@ -594,6 +594,7 @@ static int mq_attr_ok(struct mq_attr *attr)
static struct file *do_create(struct dentry *dir, struct dentry *dentry, static struct file *do_create(struct dentry *dir, struct dentry *dentry,
int oflag, mode_t mode, struct mq_attr __user *u_attr) int oflag, mode_t mode, struct mq_attr __user *u_attr)
{ {
const struct cred *cred = current_cred();
struct mq_attr attr; struct mq_attr attr;
struct file *result; struct file *result;
int ret; int ret;
...@@ -618,7 +619,7 @@ static struct file *do_create(struct dentry *dir, struct dentry *dentry, ...@@ -618,7 +619,7 @@ static struct file *do_create(struct dentry *dir, struct dentry *dentry,
if (ret) if (ret)
goto out_drop_write; goto out_drop_write;
result = dentry_open(dentry, mqueue_mnt, oflag); result = dentry_open(dentry, mqueue_mnt, oflag, cred);
/* /*
* dentry_open() took a persistent mnt_want_write(), * dentry_open() took a persistent mnt_want_write(),
* so we can now drop this one. * so we can now drop this one.
...@@ -637,7 +638,9 @@ static struct file *do_create(struct dentry *dir, struct dentry *dentry, ...@@ -637,7 +638,9 @@ static struct file *do_create(struct dentry *dir, struct dentry *dentry,
/* Opens existing queue */ /* Opens existing queue */
static struct file *do_open(struct dentry *dentry, int oflag) static struct file *do_open(struct dentry *dentry, int oflag)
{ {
static int oflag2acc[O_ACCMODE] = { MAY_READ, MAY_WRITE, const struct cred *cred = current_cred();
static const int oflag2acc[O_ACCMODE] = { MAY_READ, MAY_WRITE,
MAY_READ | MAY_WRITE }; MAY_READ | MAY_WRITE };
if ((oflag & O_ACCMODE) == (O_RDWR | O_WRONLY)) { if ((oflag & O_ACCMODE) == (O_RDWR | O_WRONLY)) {
...@@ -652,7 +655,7 @@ static int oflag2acc[O_ACCMODE] = { MAY_READ, MAY_WRITE, ...@@ -652,7 +655,7 @@ static int oflag2acc[O_ACCMODE] = { MAY_READ, MAY_WRITE,
return ERR_PTR(-EACCES); return ERR_PTR(-EACCES);
} }
return dentry_open(dentry, mqueue_mnt, oflag); return dentry_open(dentry, mqueue_mnt, oflag, cred);
} }
asmlinkage long sys_mq_open(const char __user *u_name, int oflag, mode_t mode, asmlinkage long sys_mq_open(const char __user *u_name, int oflag, mode_t mode,
......
...@@ -330,7 +330,7 @@ static int cap_file_receive(struct file *file) ...@@ -330,7 +330,7 @@ static int cap_file_receive(struct file *file)
return 0; return 0;
} }
static int cap_dentry_open(struct file *file) static int cap_dentry_open(struct file *file, const struct cred *cred)
{ {
return 0; return 0;
} }
......
...@@ -606,9 +606,9 @@ int security_file_receive(struct file *file) ...@@ -606,9 +606,9 @@ int security_file_receive(struct file *file)
return security_ops->file_receive(file); return security_ops->file_receive(file);
} }
int security_dentry_open(struct file *file) int security_dentry_open(struct file *file, const struct cred *cred)
{ {
return security_ops->dentry_open(file); return security_ops->dentry_open(file, cred);
} }
int security_task_create(unsigned long clone_flags) int security_task_create(unsigned long clone_flags)
......
...@@ -2150,9 +2150,9 @@ extern struct vfsmount *selinuxfs_mount; ...@@ -2150,9 +2150,9 @@ extern struct vfsmount *selinuxfs_mount;
extern struct dentry *selinux_null; extern struct dentry *selinux_null;
/* Derived from fs/exec.c:flush_old_files. */ /* Derived from fs/exec.c:flush_old_files. */
static inline void flush_unauthorized_files(struct files_struct *files) static inline void flush_unauthorized_files(const struct cred *cred,
struct files_struct *files)
{ {
const struct cred *cred = current_cred();
struct avc_audit_data ad; struct avc_audit_data ad;
struct file *file, *devnull = NULL; struct file *file, *devnull = NULL;
struct tty_struct *tty; struct tty_struct *tty;
...@@ -2222,7 +2222,10 @@ static inline void flush_unauthorized_files(struct files_struct *files) ...@@ -2222,7 +2222,10 @@ static inline void flush_unauthorized_files(struct files_struct *files)
if (devnull) { if (devnull) {
get_file(devnull); get_file(devnull);
} else { } else {
devnull = dentry_open(dget(selinux_null), mntget(selinuxfs_mount), O_RDWR); devnull = dentry_open(
dget(selinux_null),
mntget(selinuxfs_mount),
O_RDWR, cred);
if (IS_ERR(devnull)) { if (IS_ERR(devnull)) {
devnull = NULL; devnull = NULL;
put_unused_fd(fd); put_unused_fd(fd);
...@@ -2302,6 +2305,7 @@ static void selinux_bprm_apply_creds(struct linux_binprm *bprm, int unsafe) ...@@ -2302,6 +2305,7 @@ static void selinux_bprm_apply_creds(struct linux_binprm *bprm, int unsafe)
*/ */
static void selinux_bprm_post_apply_creds(struct linux_binprm *bprm) static void selinux_bprm_post_apply_creds(struct linux_binprm *bprm)
{ {
const struct cred *cred = current_cred();
struct task_security_struct *tsec; struct task_security_struct *tsec;
struct rlimit *rlim, *initrlim; struct rlimit *rlim, *initrlim;
struct itimerval itimer; struct itimerval itimer;
...@@ -2321,7 +2325,7 @@ static void selinux_bprm_post_apply_creds(struct linux_binprm *bprm) ...@@ -2321,7 +2325,7 @@ static void selinux_bprm_post_apply_creds(struct linux_binprm *bprm)
return; return;
/* Close files for which the new task SID is not authorized. */ /* Close files for which the new task SID is not authorized. */
flush_unauthorized_files(current->files); flush_unauthorized_files(cred, current->files);
/* Check whether the new SID can inherit signal state /* Check whether the new SID can inherit signal state
from the old SID. If not, clear itimers to avoid from the old SID. If not, clear itimers to avoid
...@@ -3202,9 +3206,8 @@ static int selinux_file_receive(struct file *file) ...@@ -3202,9 +3206,8 @@ static int selinux_file_receive(struct file *file)
return file_has_perm(cred, file, file_to_av(file)); return file_has_perm(cred, file, file_to_av(file));
} }
static int selinux_dentry_open(struct file *file) static int selinux_dentry_open(struct file *file, const struct cred *cred)
{ {
const struct cred *cred = current_cred();
struct file_security_struct *fsec; struct file_security_struct *fsec;
struct inode *inode; struct inode *inode;
struct inode_security_struct *isec; struct inode_security_struct *isec;
......
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