aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2008-11-13 18:39:22 -0500
committerJames Morris <jmorris@namei.org>2008-11-13 18:39:22 -0500
commit745ca2475a6ac596e3d8d37c2759c0fbe2586227 (patch)
treef87c34bdfbc8542477b16a014bbb4e3b415b286a
parent88e67f3b8898c5ea81d2916dd5b8bc9c0c35ba13 (diff)
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: David Howells <dhowells@redhat.com> Acked-by: James Morris <jmorris@namei.org> Signed-off-by: James Morris <jmorris@namei.org>
-rw-r--r--arch/powerpc/platforms/cell/spufs/inode.c4
-rw-r--r--arch/um/drivers/mconsole_kern.c3
-rw-r--r--fs/autofs4/dev-ioctl.c3
-rw-r--r--fs/ecryptfs/ecryptfs_kernel.h3
-rw-r--r--fs/ecryptfs/kthread.c9
-rw-r--r--fs/ecryptfs/main.c3
-rw-r--r--fs/exportfs/expfs.c4
-rw-r--r--fs/hppfs/hppfs.c6
-rw-r--r--fs/nfsctl.c3
-rw-r--r--fs/nfsd/nfs4recover.c3
-rw-r--r--fs/nfsd/vfs.c3
-rw-r--r--fs/open.c17
-rw-r--r--fs/xfs/linux-2.6/xfs_ioctl.c3
-rw-r--r--include/linux/fs.h4
-rw-r--r--include/linux/security.h7
-rw-r--r--ipc/mqueue.c11
-rw-r--r--security/capability.c2
-rw-r--r--security/security.c4
-rw-r--r--security/selinux/hooks.c15
19 files changed, 67 insertions, 40 deletions
diff --git a/arch/powerpc/platforms/cell/spufs/inode.c b/arch/powerpc/platforms/cell/spufs/inode.c
index e128ce7f0993..6296bfd9cb0b 100644
--- a/arch/powerpc/platforms/cell/spufs/inode.c
+++ b/arch/powerpc/platforms/cell/spufs/inode.c
@@ -323,7 +323,7 @@ static int spufs_context_open(struct dentry *dentry, struct vfsmount *mnt)
323 goto out; 323 goto out;
324 } 324 }
325 325
326 filp = dentry_open(dentry, mnt, O_RDONLY); 326 filp = dentry_open(dentry, mnt, O_RDONLY, current_cred());
327 if (IS_ERR(filp)) { 327 if (IS_ERR(filp)) {
328 put_unused_fd(ret); 328 put_unused_fd(ret);
329 ret = PTR_ERR(filp); 329 ret = PTR_ERR(filp);
@@ -562,7 +562,7 @@ static int spufs_gang_open(struct dentry *dentry, struct vfsmount *mnt)
562 goto out; 562 goto out;
563 } 563 }
564 564
565 filp = dentry_open(dentry, mnt, O_RDONLY); 565 filp = dentry_open(dentry, mnt, O_RDONLY, current_cred());
566 if (IS_ERR(filp)) { 566 if (IS_ERR(filp)) {
567 put_unused_fd(ret); 567 put_unused_fd(ret);
568 ret = PTR_ERR(filp); 568 ret = PTR_ERR(filp);
diff --git a/arch/um/drivers/mconsole_kern.c b/arch/um/drivers/mconsole_kern.c
index 19d579d74d27..16d3b3789a50 100644
--- a/arch/um/drivers/mconsole_kern.c
+++ b/arch/um/drivers/mconsole_kern.c
@@ -159,7 +159,8 @@ void mconsole_proc(struct mc_request *req)
159 goto out_kill; 159 goto out_kill;
160 } 160 }
161 161
162 file = dentry_open(nd.path.dentry, nd.path.mnt, O_RDONLY); 162 file = dentry_open(nd.path.dentry, nd.path.mnt, O_RDONLY,
163 current_cred());
163 if (IS_ERR(file)) { 164 if (IS_ERR(file)) {
164 mconsole_reply(req, "Failed to open file", 1, 0); 165 mconsole_reply(req, "Failed to open file", 1, 0);
165 goto out_kill; 166 goto out_kill;
diff --git a/fs/autofs4/dev-ioctl.c b/fs/autofs4/dev-ioctl.c
index 625abf5422e2..ec16255d27dd 100644
--- a/fs/autofs4/dev-ioctl.c
+++ b/fs/autofs4/dev-ioctl.c
@@ -307,7 +307,8 @@ static int autofs_dev_ioctl_open_mountpoint(const char *path, dev_t devid)
307 goto out; 307 goto out;
308 } 308 }
309 309
310 filp = dentry_open(nd.path.dentry, nd.path.mnt, O_RDONLY); 310 filp = dentry_open(nd.path.dentry, nd.path.mnt, O_RDONLY,
311 current_cred());
311 if (IS_ERR(filp)) { 312 if (IS_ERR(filp)) {
312 err = PTR_ERR(filp); 313 err = PTR_ERR(filp);
313 goto out; 314 goto out;
diff --git a/fs/ecryptfs/ecryptfs_kernel.h b/fs/ecryptfs/ecryptfs_kernel.h
index 3504cf9df358..a75026d35d16 100644
--- a/fs/ecryptfs/ecryptfs_kernel.h
+++ b/fs/ecryptfs/ecryptfs_kernel.h
@@ -691,7 +691,8 @@ int ecryptfs_init_kthread(void);
691void ecryptfs_destroy_kthread(void); 691void ecryptfs_destroy_kthread(void);
692int ecryptfs_privileged_open(struct file **lower_file, 692int ecryptfs_privileged_open(struct file **lower_file,
693 struct dentry *lower_dentry, 693 struct dentry *lower_dentry,
694 struct vfsmount *lower_mnt); 694 struct vfsmount *lower_mnt,
695 const struct cred *cred);
695int ecryptfs_init_persistent_file(struct dentry *ecryptfs_dentry); 696int ecryptfs_init_persistent_file(struct dentry *ecryptfs_dentry);
696 697
697#endif /* #ifndef ECRYPTFS_KERNEL_H */ 698#endif /* #ifndef ECRYPTFS_KERNEL_H */
diff --git a/fs/ecryptfs/kthread.c b/fs/ecryptfs/kthread.c
index c440c6b58b2d..c6d7a4d748a0 100644
--- a/fs/ecryptfs/kthread.c
+++ b/fs/ecryptfs/kthread.c
@@ -73,7 +73,7 @@ static int ecryptfs_threadfn(void *ignored)
73 mntget(req->lower_mnt); 73 mntget(req->lower_mnt);
74 (*req->lower_file) = dentry_open( 74 (*req->lower_file) = dentry_open(
75 req->lower_dentry, req->lower_mnt, 75 req->lower_dentry, req->lower_mnt,
76 (O_RDWR | O_LARGEFILE)); 76 (O_RDWR | O_LARGEFILE), current_cred());
77 req->flags |= ECRYPTFS_REQ_PROCESSED; 77 req->flags |= ECRYPTFS_REQ_PROCESSED;
78 } 78 }
79 wake_up(&req->wait); 79 wake_up(&req->wait);
@@ -132,7 +132,8 @@ void ecryptfs_destroy_kthread(void)
132 */ 132 */
133int ecryptfs_privileged_open(struct file **lower_file, 133int ecryptfs_privileged_open(struct file **lower_file,
134 struct dentry *lower_dentry, 134 struct dentry *lower_dentry,
135 struct vfsmount *lower_mnt) 135 struct vfsmount *lower_mnt,
136 const struct cred *cred)
136{ 137{
137 struct ecryptfs_open_req *req; 138 struct ecryptfs_open_req *req;
138 int rc = 0; 139 int rc = 0;
@@ -143,7 +144,7 @@ int ecryptfs_privileged_open(struct file **lower_file,
143 dget(lower_dentry); 144 dget(lower_dentry);
144 mntget(lower_mnt); 145 mntget(lower_mnt);
145 (*lower_file) = dentry_open(lower_dentry, lower_mnt, 146 (*lower_file) = dentry_open(lower_dentry, lower_mnt,
146 (O_RDWR | O_LARGEFILE)); 147 (O_RDWR | O_LARGEFILE), cred);
147 if (!IS_ERR(*lower_file)) 148 if (!IS_ERR(*lower_file))
148 goto out; 149 goto out;
149 req = kmem_cache_alloc(ecryptfs_open_req_cache, GFP_KERNEL); 150 req = kmem_cache_alloc(ecryptfs_open_req_cache, GFP_KERNEL);
@@ -184,7 +185,7 @@ int ecryptfs_privileged_open(struct file **lower_file,
184 dget(lower_dentry); 185 dget(lower_dentry);
185 mntget(lower_mnt); 186 mntget(lower_mnt);
186 (*lower_file) = dentry_open(lower_dentry, lower_mnt, 187 (*lower_file) = dentry_open(lower_dentry, lower_mnt,
187 (O_RDONLY | O_LARGEFILE)); 188 (O_RDONLY | O_LARGEFILE), cred);
188 if (IS_ERR(*lower_file)) { 189 if (IS_ERR(*lower_file)) {
189 rc = PTR_ERR(*req->lower_file); 190 rc = PTR_ERR(*req->lower_file);
190 (*lower_file) = NULL; 191 (*lower_file) = NULL;
diff --git a/fs/ecryptfs/main.c b/fs/ecryptfs/main.c
index 64d2ba980df4..fd630713c5c7 100644
--- a/fs/ecryptfs/main.c
+++ b/fs/ecryptfs/main.c
@@ -115,6 +115,7 @@ void __ecryptfs_printk(const char *fmt, ...)
115 */ 115 */
116int ecryptfs_init_persistent_file(struct dentry *ecryptfs_dentry) 116int ecryptfs_init_persistent_file(struct dentry *ecryptfs_dentry)
117{ 117{
118 const struct cred *cred = current_cred();
118 struct ecryptfs_inode_info *inode_info = 119 struct ecryptfs_inode_info *inode_info =
119 ecryptfs_inode_to_private(ecryptfs_dentry->d_inode); 120 ecryptfs_inode_to_private(ecryptfs_dentry->d_inode);
120 int rc = 0; 121 int rc = 0;
@@ -127,7 +128,7 @@ int ecryptfs_init_persistent_file(struct dentry *ecryptfs_dentry)
127 128
128 lower_dentry = ecryptfs_dentry_to_lower(ecryptfs_dentry); 129 lower_dentry = ecryptfs_dentry_to_lower(ecryptfs_dentry);
129 rc = ecryptfs_privileged_open(&inode_info->lower_file, 130 rc = ecryptfs_privileged_open(&inode_info->lower_file,
130 lower_dentry, lower_mnt); 131 lower_dentry, lower_mnt, cred);
131 if (rc || IS_ERR(inode_info->lower_file)) { 132 if (rc || IS_ERR(inode_info->lower_file)) {
132 printk(KERN_ERR "Error opening lower persistent file " 133 printk(KERN_ERR "Error opening lower persistent file "
133 "for lower_dentry [0x%p] and lower_mnt [0x%p]; " 134 "for lower_dentry [0x%p] and lower_mnt [0x%p]; "
diff --git a/fs/exportfs/expfs.c b/fs/exportfs/expfs.c
index 80246bad1b7f..ec1fb918200f 100644
--- a/fs/exportfs/expfs.c
+++ b/fs/exportfs/expfs.c
@@ -14,6 +14,7 @@
14#include <linux/module.h> 14#include <linux/module.h>
15#include <linux/mount.h> 15#include <linux/mount.h>
16#include <linux/namei.h> 16#include <linux/namei.h>
17#include <linux/sched.h>
17 18
18#define dprintk(fmt, args...) do{}while(0) 19#define dprintk(fmt, args...) do{}while(0)
19 20
@@ -249,6 +250,7 @@ static int filldir_one(void * __buf, const char * name, int len,
249static int get_name(struct vfsmount *mnt, struct dentry *dentry, 250static int get_name(struct vfsmount *mnt, struct dentry *dentry,
250 char *name, struct dentry *child) 251 char *name, struct dentry *child)
251{ 252{
253 const struct cred *cred = current_cred();
252 struct inode *dir = dentry->d_inode; 254 struct inode *dir = dentry->d_inode;
253 int error; 255 int error;
254 struct file *file; 256 struct file *file;
@@ -263,7 +265,7 @@ static int get_name(struct vfsmount *mnt, struct dentry *dentry,
263 /* 265 /*
264 * Open the directory ... 266 * Open the directory ...
265 */ 267 */
266 file = dentry_open(dget(dentry), mntget(mnt), O_RDONLY); 268 file = dentry_open(dget(dentry), mntget(mnt), O_RDONLY, cred);
267 error = PTR_ERR(file); 269 error = PTR_ERR(file);
268 if (IS_ERR(file)) 270 if (IS_ERR(file))
269 goto out; 271 goto out;
diff --git a/fs/hppfs/hppfs.c b/fs/hppfs/hppfs.c
index 2b3d1828db99..795e2c130ad7 100644
--- a/fs/hppfs/hppfs.c
+++ b/fs/hppfs/hppfs.c
@@ -426,6 +426,7 @@ static int file_mode(int fmode)
426 426
427static int hppfs_open(struct inode *inode, struct file *file) 427static int hppfs_open(struct inode *inode, struct file *file)
428{ 428{
429 const struct cred *cred = current_cred();
429 struct hppfs_private *data; 430 struct hppfs_private *data;
430 struct vfsmount *proc_mnt; 431 struct vfsmount *proc_mnt;
431 struct dentry *proc_dentry; 432 struct dentry *proc_dentry;
@@ -446,7 +447,7 @@ static int hppfs_open(struct inode *inode, struct file *file)
446 447
447 /* XXX This isn't closed anywhere */ 448 /* XXX This isn't closed anywhere */
448 data->proc_file = dentry_open(dget(proc_dentry), mntget(proc_mnt), 449 data->proc_file = dentry_open(dget(proc_dentry), mntget(proc_mnt),
449 file_mode(file->f_mode)); 450 file_mode(file->f_mode), cred);
450 err = PTR_ERR(data->proc_file); 451 err = PTR_ERR(data->proc_file);
451 if (IS_ERR(data->proc_file)) 452 if (IS_ERR(data->proc_file))
452 goto out_free1; 453 goto out_free1;
@@ -489,6 +490,7 @@ static int hppfs_open(struct inode *inode, struct file *file)
489 490
490static int hppfs_dir_open(struct inode *inode, struct file *file) 491static int hppfs_dir_open(struct inode *inode, struct file *file)
491{ 492{
493 const struct cred *cred = current_cred();
492 struct hppfs_private *data; 494 struct hppfs_private *data;
493 struct vfsmount *proc_mnt; 495 struct vfsmount *proc_mnt;
494 struct dentry *proc_dentry; 496 struct dentry *proc_dentry;
@@ -502,7 +504,7 @@ static int hppfs_dir_open(struct inode *inode, struct file *file)
502 proc_dentry = HPPFS_I(inode)->proc_dentry; 504 proc_dentry = HPPFS_I(inode)->proc_dentry;
503 proc_mnt = inode->i_sb->s_fs_info; 505 proc_mnt = inode->i_sb->s_fs_info;
504 data->proc_file = dentry_open(dget(proc_dentry), mntget(proc_mnt), 506 data->proc_file = dentry_open(dget(proc_dentry), mntget(proc_mnt),
505 file_mode(file->f_mode)); 507 file_mode(file->f_mode), cred);
506 err = PTR_ERR(data->proc_file); 508 err = PTR_ERR(data->proc_file);
507 if (IS_ERR(data->proc_file)) 509 if (IS_ERR(data->proc_file))
508 goto out_free; 510 goto out_free;
diff --git a/fs/nfsctl.c b/fs/nfsctl.c
index aed8145d9087..cc4ef2642a51 100644
--- a/fs/nfsctl.c
+++ b/fs/nfsctl.c
@@ -41,7 +41,8 @@ static struct file *do_open(char *name, int flags)
41 error = may_open(&nd, MAY_WRITE, FMODE_WRITE); 41 error = may_open(&nd, MAY_WRITE, FMODE_WRITE);
42 42
43 if (!error) 43 if (!error)
44 return dentry_open(nd.path.dentry, nd.path.mnt, flags); 44 return dentry_open(nd.path.dentry, nd.path.mnt, flags,
45 current_cred());
45 46
46 path_put(&nd.path); 47 path_put(&nd.path);
47 return ERR_PTR(error); 48 return ERR_PTR(error);
diff --git a/fs/nfsd/nfs4recover.c b/fs/nfsd/nfs4recover.c
index a5e14e8695ea..632a50b4b371 100644
--- a/fs/nfsd/nfs4recover.c
+++ b/fs/nfsd/nfs4recover.c
@@ -226,7 +226,8 @@ nfsd4_list_rec_dir(struct dentry *dir, recdir_func *f)
226 226
227 nfs4_save_user(&uid, &gid); 227 nfs4_save_user(&uid, &gid);
228 228
229 filp = dentry_open(dget(dir), mntget(rec_dir.mnt), O_RDONLY); 229 filp = dentry_open(dget(dir), mntget(rec_dir.mnt), O_RDONLY,
230 current_cred());
230 status = PTR_ERR(filp); 231 status = PTR_ERR(filp);
231 if (IS_ERR(filp)) 232 if (IS_ERR(filp))
232 goto out; 233 goto out;
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
index 890d9a68c852..b59ec5a6ed24 100644
--- a/fs/nfsd/vfs.c
+++ b/fs/nfsd/vfs.c
@@ -671,6 +671,7 @@ __be32
671nfsd_open(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, 671nfsd_open(struct svc_rqst *rqstp, struct svc_fh *fhp, int type,
672 int access, struct file **filp) 672 int access, struct file **filp)
673{ 673{
674 const struct cred *cred = current_cred();
674 struct dentry *dentry; 675 struct dentry *dentry;
675 struct inode *inode; 676 struct inode *inode;
676 int flags = O_RDONLY|O_LARGEFILE; 677 int flags = O_RDONLY|O_LARGEFILE;
@@ -725,7 +726,7 @@ nfsd_open(struct svc_rqst *rqstp, struct svc_fh *fhp, int type,
725 DQUOT_INIT(inode); 726 DQUOT_INIT(inode);
726 } 727 }
727 *filp = dentry_open(dget(dentry), mntget(fhp->fh_export->ex_path.mnt), 728 *filp = dentry_open(dget(dentry), mntget(fhp->fh_export->ex_path.mnt),
728 flags); 729 flags, cred);
729 if (IS_ERR(*filp)) 730 if (IS_ERR(*filp))
730 host_err = PTR_ERR(*filp); 731 host_err = PTR_ERR(*filp);
731out_nfserr: 732out_nfserr:
diff --git a/fs/open.c b/fs/open.c
index b1238e195e7e..f96eaab280a3 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -783,7 +783,8 @@ static inline int __get_file_write_access(struct inode *inode,
783 783
784static struct file *__dentry_open(struct dentry *dentry, struct vfsmount *mnt, 784static struct file *__dentry_open(struct dentry *dentry, struct vfsmount *mnt,
785 int flags, struct file *f, 785 int flags, struct file *f,
786 int (*open)(struct inode *, struct file *)) 786 int (*open)(struct inode *, struct file *),
787 const struct cred *cred)
787{ 788{
788 struct inode *inode; 789 struct inode *inode;
789 int error; 790 int error;
@@ -807,7 +808,7 @@ static struct file *__dentry_open(struct dentry *dentry, struct vfsmount *mnt,
807 f->f_op = fops_get(inode->i_fop); 808 f->f_op = fops_get(inode->i_fop);
808 file_move(f, &inode->i_sb->s_files); 809 file_move(f, &inode->i_sb->s_files);
809 810
810 error = security_dentry_open(f); 811 error = security_dentry_open(f, cred);
811 if (error) 812 if (error)
812 goto cleanup_all; 813 goto cleanup_all;
813 814
@@ -882,6 +883,8 @@ cleanup_file:
882struct file *lookup_instantiate_filp(struct nameidata *nd, struct dentry *dentry, 883struct file *lookup_instantiate_filp(struct nameidata *nd, struct dentry *dentry,
883 int (*open)(struct inode *, struct file *)) 884 int (*open)(struct inode *, struct file *))
884{ 885{
886 const struct cred *cred = current_cred();
887
885 if (IS_ERR(nd->intent.open.file)) 888 if (IS_ERR(nd->intent.open.file))
886 goto out; 889 goto out;
887 if (IS_ERR(dentry)) 890 if (IS_ERR(dentry))
@@ -889,7 +892,7 @@ struct file *lookup_instantiate_filp(struct nameidata *nd, struct dentry *dentry
889 nd->intent.open.file = __dentry_open(dget(dentry), mntget(nd->path.mnt), 892 nd->intent.open.file = __dentry_open(dget(dentry), mntget(nd->path.mnt),
890 nd->intent.open.flags - 1, 893 nd->intent.open.flags - 1,
891 nd->intent.open.file, 894 nd->intent.open.file,
892 open); 895 open, cred);
893out: 896out:
894 return nd->intent.open.file; 897 return nd->intent.open.file;
895out_err: 898out_err:
@@ -908,6 +911,7 @@ EXPORT_SYMBOL_GPL(lookup_instantiate_filp);
908 */ 911 */
909struct file *nameidata_to_filp(struct nameidata *nd, int flags) 912struct file *nameidata_to_filp(struct nameidata *nd, int flags)
910{ 913{
914 const struct cred *cred = current_cred();
911 struct file *filp; 915 struct file *filp;
912 916
913 /* Pick up the filp from the open intent */ 917 /* Pick up the filp from the open intent */
@@ -915,7 +919,7 @@ struct file *nameidata_to_filp(struct nameidata *nd, int flags)
915 /* Has the filesystem initialised the file for us? */ 919 /* Has the filesystem initialised the file for us? */
916 if (filp->f_path.dentry == NULL) 920 if (filp->f_path.dentry == NULL)
917 filp = __dentry_open(nd->path.dentry, nd->path.mnt, flags, filp, 921 filp = __dentry_open(nd->path.dentry, nd->path.mnt, flags, filp,
918 NULL); 922 NULL, cred);
919 else 923 else
920 path_put(&nd->path); 924 path_put(&nd->path);
921 return filp; 925 return filp;
@@ -925,7 +929,8 @@ struct file *nameidata_to_filp(struct nameidata *nd, int flags)
925 * dentry_open() will have done dput(dentry) and mntput(mnt) if it returns an 929 * dentry_open() will have done dput(dentry) and mntput(mnt) if it returns an
926 * error. 930 * error.
927 */ 931 */
928struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags) 932struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags,
933 const struct cred *cred)
929{ 934{
930 int error; 935 int error;
931 struct file *f; 936 struct file *f;
@@ -950,7 +955,7 @@ struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags)
950 return ERR_PTR(error); 955 return ERR_PTR(error);
951 } 956 }
952 957
953 return __dentry_open(dentry, mnt, flags, f, NULL); 958 return __dentry_open(dentry, mnt, flags, f, NULL, cred);
954} 959}
955EXPORT_SYMBOL(dentry_open); 960EXPORT_SYMBOL(dentry_open);
956 961
diff --git a/fs/xfs/linux-2.6/xfs_ioctl.c b/fs/xfs/linux-2.6/xfs_ioctl.c
index 67c72aec97e6..281cbd5a25cf 100644
--- a/fs/xfs/linux-2.6/xfs_ioctl.c
+++ b/fs/xfs/linux-2.6/xfs_ioctl.c
@@ -256,6 +256,7 @@ xfs_open_by_handle(
256 struct file *parfilp, 256 struct file *parfilp,
257 struct inode *parinode) 257 struct inode *parinode)
258{ 258{
259 const struct cred *cred = current_cred();
259 int error; 260 int error;
260 int new_fd; 261 int new_fd;
261 int permflag; 262 int permflag;
@@ -321,7 +322,7 @@ xfs_open_by_handle(
321 mntget(parfilp->f_path.mnt); 322 mntget(parfilp->f_path.mnt);
322 323
323 /* Create file pointer. */ 324 /* Create file pointer. */
324 filp = dentry_open(dentry, parfilp->f_path.mnt, hreq.oflags); 325 filp = dentry_open(dentry, parfilp->f_path.mnt, hreq.oflags, cred);
325 if (IS_ERR(filp)) { 326 if (IS_ERR(filp)) {
326 put_unused_fd(new_fd); 327 put_unused_fd(new_fd);
327 return -XFS_ERROR(-PTR_ERR(filp)); 328 return -XFS_ERROR(-PTR_ERR(filp));
diff --git a/include/linux/fs.h b/include/linux/fs.h
index b3d404aaabed..3bfec1327b8d 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -315,6 +315,7 @@ struct poll_table_struct;
315struct kstatfs; 315struct kstatfs;
316struct vm_area_struct; 316struct vm_area_struct;
317struct vfsmount; 317struct vfsmount;
318struct cred;
318 319
319extern void __init inode_init(void); 320extern void __init inode_init(void);
320extern void __init inode_init_early(void); 321extern void __init inode_init_early(void);
@@ -1673,7 +1674,8 @@ extern int do_truncate(struct dentry *, loff_t start, unsigned int time_attrs,
1673extern long do_sys_open(int dfd, const char __user *filename, int flags, 1674extern long do_sys_open(int dfd, const char __user *filename, int flags,
1674 int mode); 1675 int mode);
1675extern struct file *filp_open(const char *, int, int); 1676extern struct file *filp_open(const char *, int, int);
1676extern struct file * dentry_open(struct dentry *, struct vfsmount *, int); 1677extern struct file * dentry_open(struct dentry *, struct vfsmount *, int,
1678 const struct cred *);
1677extern int filp_close(struct file *, fl_owner_t id); 1679extern int filp_close(struct file *, fl_owner_t id);
1678extern char * getname(const char __user *); 1680extern char * getname(const char __user *);
1679 1681
diff --git a/include/linux/security.h b/include/linux/security.h
index 9239cc11eb9c..7e9fe046a0d1 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -1402,7 +1402,7 @@ struct security_operations {
1402 int (*file_send_sigiotask) (struct task_struct *tsk, 1402 int (*file_send_sigiotask) (struct task_struct *tsk,
1403 struct fown_struct *fown, int sig); 1403 struct fown_struct *fown, int sig);
1404 int (*file_receive) (struct file *file); 1404 int (*file_receive) (struct file *file);
1405 int (*dentry_open) (struct file *file); 1405 int (*dentry_open) (struct file *file, const struct cred *cred);
1406 1406
1407 int (*task_create) (unsigned long clone_flags); 1407 int (*task_create) (unsigned long clone_flags);
1408 int (*cred_alloc_security) (struct cred *cred); 1408 int (*cred_alloc_security) (struct cred *cred);
@@ -1658,7 +1658,7 @@ int security_file_set_fowner(struct file *file);
1658int security_file_send_sigiotask(struct task_struct *tsk, 1658int security_file_send_sigiotask(struct task_struct *tsk,
1659 struct fown_struct *fown, int sig); 1659 struct fown_struct *fown, int sig);
1660int security_file_receive(struct file *file); 1660int security_file_receive(struct file *file);
1661int security_dentry_open(struct file *file); 1661int security_dentry_open(struct file *file, const struct cred *cred);
1662int security_task_create(unsigned long clone_flags); 1662int security_task_create(unsigned long clone_flags);
1663int security_cred_alloc(struct cred *cred); 1663int security_cred_alloc(struct cred *cred);
1664void security_cred_free(struct cred *cred); 1664void security_cred_free(struct cred *cred);
@@ -2171,7 +2171,8 @@ static inline int security_file_receive(struct file *file)
2171 return 0; 2171 return 0;
2172} 2172}
2173 2173
2174static inline int security_dentry_open(struct file *file) 2174static inline int security_dentry_open(struct file *file,
2175 const struct cred *cred)
2175{ 2176{
2176 return 0; 2177 return 0;
2177} 2178}
diff --git a/ipc/mqueue.c b/ipc/mqueue.c
index 1151881ccb9a..d9393f8e4c3e 100644
--- a/ipc/mqueue.c
+++ b/ipc/mqueue.c
@@ -594,6 +594,7 @@ static int mq_attr_ok(struct mq_attr *attr)
594static struct file *do_create(struct dentry *dir, struct dentry *dentry, 594static struct file *do_create(struct dentry *dir, struct dentry *dentry,
595 int oflag, mode_t mode, struct mq_attr __user *u_attr) 595 int oflag, mode_t mode, struct mq_attr __user *u_attr)
596{ 596{
597 const struct cred *cred = current_cred();
597 struct mq_attr attr; 598 struct mq_attr attr;
598 struct file *result; 599 struct file *result;
599 int ret; 600 int ret;
@@ -618,7 +619,7 @@ static struct file *do_create(struct dentry *dir, struct dentry *dentry,
618 if (ret) 619 if (ret)
619 goto out_drop_write; 620 goto out_drop_write;
620 621
621 result = dentry_open(dentry, mqueue_mnt, oflag); 622 result = dentry_open(dentry, mqueue_mnt, oflag, cred);
622 /* 623 /*
623 * dentry_open() took a persistent mnt_want_write(), 624 * dentry_open() took a persistent mnt_want_write(),
624 * so we can now drop this one. 625 * so we can now drop this one.
@@ -637,8 +638,10 @@ out:
637/* Opens existing queue */ 638/* Opens existing queue */
638static struct file *do_open(struct dentry *dentry, int oflag) 639static struct file *do_open(struct dentry *dentry, int oflag)
639{ 640{
640static int oflag2acc[O_ACCMODE] = { MAY_READ, MAY_WRITE, 641 const struct cred *cred = current_cred();
641 MAY_READ | MAY_WRITE }; 642
643 static const int oflag2acc[O_ACCMODE] = { MAY_READ, MAY_WRITE,
644 MAY_READ | MAY_WRITE };
642 645
643 if ((oflag & O_ACCMODE) == (O_RDWR | O_WRONLY)) { 646 if ((oflag & O_ACCMODE) == (O_RDWR | O_WRONLY)) {
644 dput(dentry); 647 dput(dentry);
@@ -652,7 +655,7 @@ static int oflag2acc[O_ACCMODE] = { MAY_READ, MAY_WRITE,
652 return ERR_PTR(-EACCES); 655 return ERR_PTR(-EACCES);
653 } 656 }
654 657
655 return dentry_open(dentry, mqueue_mnt, oflag); 658 return dentry_open(dentry, mqueue_mnt, oflag, cred);
656} 659}
657 660
658asmlinkage long sys_mq_open(const char __user *u_name, int oflag, mode_t mode, 661asmlinkage long sys_mq_open(const char __user *u_name, int oflag, mode_t mode,
diff --git a/security/capability.c b/security/capability.c
index 6c4b5137ca7b..fac2f61b69a9 100644
--- a/security/capability.c
+++ b/security/capability.c
@@ -330,7 +330,7 @@ static int cap_file_receive(struct file *file)
330 return 0; 330 return 0;
331} 331}
332 332
333static int cap_dentry_open(struct file *file) 333static int cap_dentry_open(struct file *file, const struct cred *cred)
334{ 334{
335 return 0; 335 return 0;
336} 336}
diff --git a/security/security.c b/security/security.c
index d058f7d5b10a..f40a0a04c3c2 100644
--- a/security/security.c
+++ b/security/security.c
@@ -606,9 +606,9 @@ int security_file_receive(struct file *file)
606 return security_ops->file_receive(file); 606 return security_ops->file_receive(file);
607} 607}
608 608
609int security_dentry_open(struct file *file) 609int security_dentry_open(struct file *file, const struct cred *cred)
610{ 610{
611 return security_ops->dentry_open(file); 611 return security_ops->dentry_open(file, cred);
612} 612}
613 613
614int security_task_create(unsigned long clone_flags) 614int security_task_create(unsigned long clone_flags)
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index cc6e5a3f10cc..f20cbd681ba6 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -2150,9 +2150,9 @@ extern struct vfsmount *selinuxfs_mount;
2150extern struct dentry *selinux_null; 2150extern struct dentry *selinux_null;
2151 2151
2152/* Derived from fs/exec.c:flush_old_files. */ 2152/* Derived from fs/exec.c:flush_old_files. */
2153static inline void flush_unauthorized_files(struct files_struct *files) 2153static inline void flush_unauthorized_files(const struct cred *cred,
2154 struct files_struct *files)
2154{ 2155{
2155 const struct cred *cred = current_cred();
2156 struct avc_audit_data ad; 2156 struct avc_audit_data ad;
2157 struct file *file, *devnull = NULL; 2157 struct file *file, *devnull = NULL;
2158 struct tty_struct *tty; 2158 struct tty_struct *tty;
@@ -2222,7 +2222,10 @@ static inline void flush_unauthorized_files(struct files_struct *files)
2222 if (devnull) { 2222 if (devnull) {
2223 get_file(devnull); 2223 get_file(devnull);
2224 } else { 2224 } else {
2225 devnull = dentry_open(dget(selinux_null), mntget(selinuxfs_mount), O_RDWR); 2225 devnull = dentry_open(
2226 dget(selinux_null),
2227 mntget(selinuxfs_mount),
2228 O_RDWR, cred);
2226 if (IS_ERR(devnull)) { 2229 if (IS_ERR(devnull)) {
2227 devnull = NULL; 2230 devnull = NULL;
2228 put_unused_fd(fd); 2231 put_unused_fd(fd);
@@ -2302,6 +2305,7 @@ static void selinux_bprm_apply_creds(struct linux_binprm *bprm, int unsafe)
2302 */ 2305 */
2303static void selinux_bprm_post_apply_creds(struct linux_binprm *bprm) 2306static void selinux_bprm_post_apply_creds(struct linux_binprm *bprm)
2304{ 2307{
2308 const struct cred *cred = current_cred();
2305 struct task_security_struct *tsec; 2309 struct task_security_struct *tsec;
2306 struct rlimit *rlim, *initrlim; 2310 struct rlimit *rlim, *initrlim;
2307 struct itimerval itimer; 2311 struct itimerval itimer;
@@ -2321,7 +2325,7 @@ static void selinux_bprm_post_apply_creds(struct linux_binprm *bprm)
2321 return; 2325 return;
2322 2326
2323 /* Close files for which the new task SID is not authorized. */ 2327 /* Close files for which the new task SID is not authorized. */
2324 flush_unauthorized_files(current->files); 2328 flush_unauthorized_files(cred, current->files);
2325 2329
2326 /* Check whether the new SID can inherit signal state 2330 /* Check whether the new SID can inherit signal state
2327 from the old SID. If not, clear itimers to avoid 2331 from the old SID. If not, clear itimers to avoid
@@ -3202,9 +3206,8 @@ static int selinux_file_receive(struct file *file)
3202 return file_has_perm(cred, file, file_to_av(file)); 3206 return file_has_perm(cred, file, file_to_av(file));
3203} 3207}
3204 3208
3205static int selinux_dentry_open(struct file *file) 3209static int selinux_dentry_open(struct file *file, const struct cred *cred)
3206{ 3210{
3207 const struct cred *cred = current_cred();
3208 struct file_security_struct *fsec; 3211 struct file_security_struct *fsec;
3209 struct inode *inode; 3212 struct inode *inode;
3210 struct inode_security_struct *isec; 3213 struct inode_security_struct *isec;