diff options
author | David Howells <dhowells@redhat.com> | 2008-11-13 18:39:22 -0500 |
---|---|---|
committer | James Morris <jmorris@namei.org> | 2008-11-13 18:39:22 -0500 |
commit | 745ca2475a6ac596e3d8d37c2759c0fbe2586227 (patch) | |
tree | f87c34bdfbc8542477b16a014bbb4e3b415b286a | |
parent | 88e67f3b8898c5ea81d2916dd5b8bc9c0c35ba13 (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.c | 4 | ||||
-rw-r--r-- | arch/um/drivers/mconsole_kern.c | 3 | ||||
-rw-r--r-- | fs/autofs4/dev-ioctl.c | 3 | ||||
-rw-r--r-- | fs/ecryptfs/ecryptfs_kernel.h | 3 | ||||
-rw-r--r-- | fs/ecryptfs/kthread.c | 9 | ||||
-rw-r--r-- | fs/ecryptfs/main.c | 3 | ||||
-rw-r--r-- | fs/exportfs/expfs.c | 4 | ||||
-rw-r--r-- | fs/hppfs/hppfs.c | 6 | ||||
-rw-r--r-- | fs/nfsctl.c | 3 | ||||
-rw-r--r-- | fs/nfsd/nfs4recover.c | 3 | ||||
-rw-r--r-- | fs/nfsd/vfs.c | 3 | ||||
-rw-r--r-- | fs/open.c | 17 | ||||
-rw-r--r-- | fs/xfs/linux-2.6/xfs_ioctl.c | 3 | ||||
-rw-r--r-- | include/linux/fs.h | 4 | ||||
-rw-r--r-- | include/linux/security.h | 7 | ||||
-rw-r--r-- | ipc/mqueue.c | 11 | ||||
-rw-r--r-- | security/capability.c | 2 | ||||
-rw-r--r-- | security/security.c | 4 | ||||
-rw-r--r-- | security/selinux/hooks.c | 15 |
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); | |||
691 | void ecryptfs_destroy_kthread(void); | 691 | void ecryptfs_destroy_kthread(void); |
692 | int ecryptfs_privileged_open(struct file **lower_file, | 692 | int 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); | ||
695 | int ecryptfs_init_persistent_file(struct dentry *ecryptfs_dentry); | 696 | int 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 | */ |
133 | int ecryptfs_privileged_open(struct file **lower_file, | 133 | int 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 | */ |
116 | int ecryptfs_init_persistent_file(struct dentry *ecryptfs_dentry) | 116 | int 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, | |||
249 | static int get_name(struct vfsmount *mnt, struct dentry *dentry, | 250 | static 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 | ||
427 | static int hppfs_open(struct inode *inode, struct file *file) | 427 | static 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 | ||
490 | static int hppfs_dir_open(struct inode *inode, struct file *file) | 491 | static 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 | |||
671 | nfsd_open(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, | 671 | nfsd_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); |
731 | out_nfserr: | 732 | out_nfserr: |
@@ -783,7 +783,8 @@ static inline int __get_file_write_access(struct inode *inode, | |||
783 | 783 | ||
784 | static struct file *__dentry_open(struct dentry *dentry, struct vfsmount *mnt, | 784 | static 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: | |||
882 | struct file *lookup_instantiate_filp(struct nameidata *nd, struct dentry *dentry, | 883 | struct 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); |
893 | out: | 896 | out: |
894 | return nd->intent.open.file; | 897 | return nd->intent.open.file; |
895 | out_err: | 898 | out_err: |
@@ -908,6 +911,7 @@ EXPORT_SYMBOL_GPL(lookup_instantiate_filp); | |||
908 | */ | 911 | */ |
909 | struct file *nameidata_to_filp(struct nameidata *nd, int flags) | 912 | struct 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 | */ |
928 | struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags) | 932 | struct 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 | } |
955 | EXPORT_SYMBOL(dentry_open); | 960 | EXPORT_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; | |||
315 | struct kstatfs; | 315 | struct kstatfs; |
316 | struct vm_area_struct; | 316 | struct vm_area_struct; |
317 | struct vfsmount; | 317 | struct vfsmount; |
318 | struct cred; | ||
318 | 319 | ||
319 | extern void __init inode_init(void); | 320 | extern void __init inode_init(void); |
320 | extern void __init inode_init_early(void); | 321 | 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 | extern long do_sys_open(int dfd, const char __user *filename, int flags, | 1674 | extern long do_sys_open(int dfd, const char __user *filename, int flags, |
1674 | int mode); | 1675 | int mode); |
1675 | extern struct file *filp_open(const char *, int, int); | 1676 | extern struct file *filp_open(const char *, int, int); |
1676 | extern struct file * dentry_open(struct dentry *, struct vfsmount *, int); | 1677 | extern struct file * dentry_open(struct dentry *, struct vfsmount *, int, |
1678 | const struct cred *); | ||
1677 | extern int filp_close(struct file *, fl_owner_t id); | 1679 | extern int filp_close(struct file *, fl_owner_t id); |
1678 | extern char * getname(const char __user *); | 1680 | extern 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); | |||
1658 | int security_file_send_sigiotask(struct task_struct *tsk, | 1658 | int security_file_send_sigiotask(struct task_struct *tsk, |
1659 | struct fown_struct *fown, int sig); | 1659 | struct fown_struct *fown, int sig); |
1660 | int security_file_receive(struct file *file); | 1660 | int security_file_receive(struct file *file); |
1661 | int security_dentry_open(struct file *file); | 1661 | int security_dentry_open(struct file *file, const struct cred *cred); |
1662 | int security_task_create(unsigned long clone_flags); | 1662 | int security_task_create(unsigned long clone_flags); |
1663 | int security_cred_alloc(struct cred *cred); | 1663 | int security_cred_alloc(struct cred *cred); |
1664 | void security_cred_free(struct cred *cred); | 1664 | void 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 | ||
2174 | static inline int security_dentry_open(struct file *file) | 2174 | static 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) | |||
594 | static struct file *do_create(struct dentry *dir, struct dentry *dentry, | 594 | static 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 */ |
638 | static struct file *do_open(struct dentry *dentry, int oflag) | 639 | static struct file *do_open(struct dentry *dentry, int oflag) |
639 | { | 640 | { |
640 | static 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 | ||
658 | asmlinkage long sys_mq_open(const char __user *u_name, int oflag, mode_t mode, | 661 | asmlinkage 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 | ||
333 | static int cap_dentry_open(struct file *file) | 333 | static 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 | ||
609 | int security_dentry_open(struct file *file) | 609 | int 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 | ||
614 | int security_task_create(unsigned long clone_flags) | 614 | int 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; | |||
2150 | extern struct dentry *selinux_null; | 2150 | extern struct dentry *selinux_null; |
2151 | 2151 | ||
2152 | /* Derived from fs/exec.c:flush_old_files. */ | 2152 | /* Derived from fs/exec.c:flush_old_files. */ |
2153 | static inline void flush_unauthorized_files(struct files_struct *files) | 2153 | static 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 | */ |
2303 | static void selinux_bprm_post_apply_creds(struct linux_binprm *bprm) | 2306 | static 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 | ||
3205 | static int selinux_dentry_open(struct file *file) | 3209 | static 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; |