Skip to content

Commit 745ca24

Browse files
dhowellsJames Morris
authored andcommitted
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>
1 parent 88e67f3 commit 745ca24

File tree

19 files changed

+67
-40
lines changed

19 files changed

+67
-40
lines changed

arch/powerpc/platforms/cell/spufs/inode.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -323,7 +323,7 @@ static int spufs_context_open(struct dentry *dentry, struct vfsmount *mnt)
323323
goto out;
324324
}
325325

326-
filp = dentry_open(dentry, mnt, O_RDONLY);
326+
filp = dentry_open(dentry, mnt, O_RDONLY, current_cred());
327327
if (IS_ERR(filp)) {
328328
put_unused_fd(ret);
329329
ret = PTR_ERR(filp);
@@ -562,7 +562,7 @@ static int spufs_gang_open(struct dentry *dentry, struct vfsmount *mnt)
562562
goto out;
563563
}
564564

565-
filp = dentry_open(dentry, mnt, O_RDONLY);
565+
filp = dentry_open(dentry, mnt, O_RDONLY, current_cred());
566566
if (IS_ERR(filp)) {
567567
put_unused_fd(ret);
568568
ret = PTR_ERR(filp);

arch/um/drivers/mconsole_kern.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,8 @@ void mconsole_proc(struct mc_request *req)
159159
goto out_kill;
160160
}
161161

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());
163164
if (IS_ERR(file)) {
164165
mconsole_reply(req, "Failed to open file", 1, 0);
165166
goto out_kill;

fs/autofs4/dev-ioctl.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -307,7 +307,8 @@ static int autofs_dev_ioctl_open_mountpoint(const char *path, dev_t devid)
307307
goto out;
308308
}
309309

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());
311312
if (IS_ERR(filp)) {
312313
err = PTR_ERR(filp);
313314
goto out;

fs/ecryptfs/ecryptfs_kernel.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -691,7 +691,8 @@ int ecryptfs_init_kthread(void);
691691
void ecryptfs_destroy_kthread(void);
692692
int ecryptfs_privileged_open(struct file **lower_file,
693693
struct dentry *lower_dentry,
694-
struct vfsmount *lower_mnt);
694+
struct vfsmount *lower_mnt,
695+
const struct cred *cred);
695696
int ecryptfs_init_persistent_file(struct dentry *ecryptfs_dentry);
696697

697698
#endif /* #ifndef ECRYPTFS_KERNEL_H */

fs/ecryptfs/kthread.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ static int ecryptfs_threadfn(void *ignored)
7373
mntget(req->lower_mnt);
7474
(*req->lower_file) = dentry_open(
7575
req->lower_dentry, req->lower_mnt,
76-
(O_RDWR | O_LARGEFILE));
76+
(O_RDWR | O_LARGEFILE), current_cred());
7777
req->flags |= ECRYPTFS_REQ_PROCESSED;
7878
}
7979
wake_up(&req->wait);
@@ -132,7 +132,8 @@ void ecryptfs_destroy_kthread(void)
132132
*/
133133
int ecryptfs_privileged_open(struct file **lower_file,
134134
struct dentry *lower_dentry,
135-
struct vfsmount *lower_mnt)
135+
struct vfsmount *lower_mnt,
136+
const struct cred *cred)
136137
{
137138
struct ecryptfs_open_req *req;
138139
int rc = 0;
@@ -143,7 +144,7 @@ int ecryptfs_privileged_open(struct file **lower_file,
143144
dget(lower_dentry);
144145
mntget(lower_mnt);
145146
(*lower_file) = dentry_open(lower_dentry, lower_mnt,
146-
(O_RDWR | O_LARGEFILE));
147+
(O_RDWR | O_LARGEFILE), cred);
147148
if (!IS_ERR(*lower_file))
148149
goto out;
149150
req = kmem_cache_alloc(ecryptfs_open_req_cache, GFP_KERNEL);
@@ -184,7 +185,7 @@ int ecryptfs_privileged_open(struct file **lower_file,
184185
dget(lower_dentry);
185186
mntget(lower_mnt);
186187
(*lower_file) = dentry_open(lower_dentry, lower_mnt,
187-
(O_RDONLY | O_LARGEFILE));
188+
(O_RDONLY | O_LARGEFILE), cred);
188189
if (IS_ERR(*lower_file)) {
189190
rc = PTR_ERR(*req->lower_file);
190191
(*lower_file) = NULL;

fs/ecryptfs/main.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,7 @@ void __ecryptfs_printk(const char *fmt, ...)
115115
*/
116116
int ecryptfs_init_persistent_file(struct dentry *ecryptfs_dentry)
117117
{
118+
const struct cred *cred = current_cred();
118119
struct ecryptfs_inode_info *inode_info =
119120
ecryptfs_inode_to_private(ecryptfs_dentry->d_inode);
120121
int rc = 0;
@@ -127,7 +128,7 @@ int ecryptfs_init_persistent_file(struct dentry *ecryptfs_dentry)
127128

128129
lower_dentry = ecryptfs_dentry_to_lower(ecryptfs_dentry);
129130
rc = ecryptfs_privileged_open(&inode_info->lower_file,
130-
lower_dentry, lower_mnt);
131+
lower_dentry, lower_mnt, cred);
131132
if (rc || IS_ERR(inode_info->lower_file)) {
132133
printk(KERN_ERR "Error opening lower persistent file "
133134
"for lower_dentry [0x%p] and lower_mnt [0x%p]; "

fs/exportfs/expfs.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include <linux/module.h>
1515
#include <linux/mount.h>
1616
#include <linux/namei.h>
17+
#include <linux/sched.h>
1718

1819
#define dprintk(fmt, args...) do{}while(0)
1920

@@ -249,6 +250,7 @@ static int filldir_one(void * __buf, const char * name, int len,
249250
static int get_name(struct vfsmount *mnt, struct dentry *dentry,
250251
char *name, struct dentry *child)
251252
{
253+
const struct cred *cred = current_cred();
252254
struct inode *dir = dentry->d_inode;
253255
int error;
254256
struct file *file;
@@ -263,7 +265,7 @@ static int get_name(struct vfsmount *mnt, struct dentry *dentry,
263265
/*
264266
* Open the directory ...
265267
*/
266-
file = dentry_open(dget(dentry), mntget(mnt), O_RDONLY);
268+
file = dentry_open(dget(dentry), mntget(mnt), O_RDONLY, cred);
267269
error = PTR_ERR(file);
268270
if (IS_ERR(file))
269271
goto out;

fs/hppfs/hppfs.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -426,6 +426,7 @@ static int file_mode(int fmode)
426426

427427
static int hppfs_open(struct inode *inode, struct file *file)
428428
{
429+
const struct cred *cred = current_cred();
429430
struct hppfs_private *data;
430431
struct vfsmount *proc_mnt;
431432
struct dentry *proc_dentry;
@@ -446,7 +447,7 @@ static int hppfs_open(struct inode *inode, struct file *file)
446447

447448
/* XXX This isn't closed anywhere */
448449
data->proc_file = dentry_open(dget(proc_dentry), mntget(proc_mnt),
449-
file_mode(file->f_mode));
450+
file_mode(file->f_mode), cred);
450451
err = PTR_ERR(data->proc_file);
451452
if (IS_ERR(data->proc_file))
452453
goto out_free1;
@@ -489,6 +490,7 @@ static int hppfs_open(struct inode *inode, struct file *file)
489490

490491
static int hppfs_dir_open(struct inode *inode, struct file *file)
491492
{
493+
const struct cred *cred = current_cred();
492494
struct hppfs_private *data;
493495
struct vfsmount *proc_mnt;
494496
struct dentry *proc_dentry;
@@ -502,7 +504,7 @@ static int hppfs_dir_open(struct inode *inode, struct file *file)
502504
proc_dentry = HPPFS_I(inode)->proc_dentry;
503505
proc_mnt = inode->i_sb->s_fs_info;
504506
data->proc_file = dentry_open(dget(proc_dentry), mntget(proc_mnt),
505-
file_mode(file->f_mode));
507+
file_mode(file->f_mode), cred);
506508
err = PTR_ERR(data->proc_file);
507509
if (IS_ERR(data->proc_file))
508510
goto out_free;

fs/nfsctl.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,8 @@ static struct file *do_open(char *name, int flags)
4141
error = may_open(&nd, MAY_WRITE, FMODE_WRITE);
4242

4343
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());
4546

4647
path_put(&nd.path);
4748
return ERR_PTR(error);

fs/nfsd/nfs4recover.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -226,7 +226,8 @@ nfsd4_list_rec_dir(struct dentry *dir, recdir_func *f)
226226

227227
nfs4_save_user(&uid, &gid);
228228

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());
230231
status = PTR_ERR(filp);
231232
if (IS_ERR(filp))
232233
goto out;

fs/nfsd/vfs.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -671,6 +671,7 @@ __be32
671671
nfsd_open(struct svc_rqst *rqstp, struct svc_fh *fhp, int type,
672672
int access, struct file **filp)
673673
{
674+
const struct cred *cred = current_cred();
674675
struct dentry *dentry;
675676
struct inode *inode;
676677
int flags = O_RDONLY|O_LARGEFILE;
@@ -725,7 +726,7 @@ nfsd_open(struct svc_rqst *rqstp, struct svc_fh *fhp, int type,
725726
DQUOT_INIT(inode);
726727
}
727728
*filp = dentry_open(dget(dentry), mntget(fhp->fh_export->ex_path.mnt),
728-
flags);
729+
flags, cred);
729730
if (IS_ERR(*filp))
730731
host_err = PTR_ERR(*filp);
731732
out_nfserr:

fs/open.c

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -783,7 +783,8 @@ static inline int __get_file_write_access(struct inode *inode,
783783

784784
static struct file *__dentry_open(struct dentry *dentry, struct vfsmount *mnt,
785785
int flags, struct file *f,
786-
int (*open)(struct inode *, struct file *))
786+
int (*open)(struct inode *, struct file *),
787+
const struct cred *cred)
787788
{
788789
struct inode *inode;
789790
int error;
@@ -807,7 +808,7 @@ static struct file *__dentry_open(struct dentry *dentry, struct vfsmount *mnt,
807808
f->f_op = fops_get(inode->i_fop);
808809
file_move(f, &inode->i_sb->s_files);
809810

810-
error = security_dentry_open(f);
811+
error = security_dentry_open(f, cred);
811812
if (error)
812813
goto cleanup_all;
813814

@@ -882,14 +883,16 @@ static struct file *__dentry_open(struct dentry *dentry, struct vfsmount *mnt,
882883
struct file *lookup_instantiate_filp(struct nameidata *nd, struct dentry *dentry,
883884
int (*open)(struct inode *, struct file *))
884885
{
886+
const struct cred *cred = current_cred();
887+
885888
if (IS_ERR(nd->intent.open.file))
886889
goto out;
887890
if (IS_ERR(dentry))
888891
goto out_err;
889892
nd->intent.open.file = __dentry_open(dget(dentry), mntget(nd->path.mnt),
890893
nd->intent.open.flags - 1,
891894
nd->intent.open.file,
892-
open);
895+
open, cred);
893896
out:
894897
return nd->intent.open.file;
895898
out_err:
@@ -908,14 +911,15 @@ EXPORT_SYMBOL_GPL(lookup_instantiate_filp);
908911
*/
909912
struct file *nameidata_to_filp(struct nameidata *nd, int flags)
910913
{
914+
const struct cred *cred = current_cred();
911915
struct file *filp;
912916

913917
/* Pick up the filp from the open intent */
914918
filp = nd->intent.open.file;
915919
/* Has the filesystem initialised the file for us? */
916920
if (filp->f_path.dentry == NULL)
917921
filp = __dentry_open(nd->path.dentry, nd->path.mnt, flags, filp,
918-
NULL);
922+
NULL, cred);
919923
else
920924
path_put(&nd->path);
921925
return filp;
@@ -925,7 +929,8 @@ struct file *nameidata_to_filp(struct nameidata *nd, int flags)
925929
* dentry_open() will have done dput(dentry) and mntput(mnt) if it returns an
926930
* error.
927931
*/
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)
929934
{
930935
int error;
931936
struct file *f;
@@ -950,7 +955,7 @@ struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags)
950955
return ERR_PTR(error);
951956
}
952957

953-
return __dentry_open(dentry, mnt, flags, f, NULL);
958+
return __dentry_open(dentry, mnt, flags, f, NULL, cred);
954959
}
955960
EXPORT_SYMBOL(dentry_open);
956961

fs/xfs/linux-2.6/xfs_ioctl.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,7 @@ xfs_open_by_handle(
256256
struct file *parfilp,
257257
struct inode *parinode)
258258
{
259+
const struct cred *cred = current_cred();
259260
int error;
260261
int new_fd;
261262
int permflag;
@@ -321,7 +322,7 @@ xfs_open_by_handle(
321322
mntget(parfilp->f_path.mnt);
322323

323324
/* 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);
325326
if (IS_ERR(filp)) {
326327
put_unused_fd(new_fd);
327328
return -XFS_ERROR(-PTR_ERR(filp));

include/linux/fs.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -315,6 +315,7 @@ struct poll_table_struct;
315315
struct kstatfs;
316316
struct vm_area_struct;
317317
struct vfsmount;
318+
struct cred;
318319

319320
extern void __init inode_init(void);
320321
extern void __init inode_init_early(void);
@@ -1673,7 +1674,8 @@ extern int do_truncate(struct dentry *, loff_t start, unsigned int time_attrs,
16731674
extern long do_sys_open(int dfd, const char __user *filename, int flags,
16741675
int mode);
16751676
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 *);
16771679
extern int filp_close(struct file *, fl_owner_t id);
16781680
extern char * getname(const char __user *);
16791681

include/linux/security.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1402,7 +1402,7 @@ struct security_operations {
14021402
int (*file_send_sigiotask) (struct task_struct *tsk,
14031403
struct fown_struct *fown, int sig);
14041404
int (*file_receive) (struct file *file);
1405-
int (*dentry_open) (struct file *file);
1405+
int (*dentry_open) (struct file *file, const struct cred *cred);
14061406

14071407
int (*task_create) (unsigned long clone_flags);
14081408
int (*cred_alloc_security) (struct cred *cred);
@@ -1658,7 +1658,7 @@ int security_file_set_fowner(struct file *file);
16581658
int security_file_send_sigiotask(struct task_struct *tsk,
16591659
struct fown_struct *fown, int sig);
16601660
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);
16621662
int security_task_create(unsigned long clone_flags);
16631663
int security_cred_alloc(struct cred *cred);
16641664
void security_cred_free(struct cred *cred);
@@ -2171,7 +2171,8 @@ static inline int security_file_receive(struct file *file)
21712171
return 0;
21722172
}
21732173

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)
21752176
{
21762177
return 0;
21772178
}

ipc/mqueue.c

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -594,6 +594,7 @@ static int mq_attr_ok(struct mq_attr *attr)
594594
static struct file *do_create(struct dentry *dir, struct dentry *dentry,
595595
int oflag, mode_t mode, struct mq_attr __user *u_attr)
596596
{
597+
const struct cred *cred = current_cred();
597598
struct mq_attr attr;
598599
struct file *result;
599600
int ret;
@@ -618,7 +619,7 @@ static struct file *do_create(struct dentry *dir, struct dentry *dentry,
618619
if (ret)
619620
goto out_drop_write;
620621

621-
result = dentry_open(dentry, mqueue_mnt, oflag);
622+
result = dentry_open(dentry, mqueue_mnt, oflag, cred);
622623
/*
623624
* dentry_open() took a persistent mnt_want_write(),
624625
* so we can now drop this one.
@@ -637,8 +638,10 @@ static struct file *do_create(struct dentry *dir, struct dentry *dentry,
637638
/* Opens existing queue */
638639
static struct file *do_open(struct dentry *dentry, int oflag)
639640
{
640-
static int oflag2acc[O_ACCMODE] = { MAY_READ, MAY_WRITE,
641-
MAY_READ | MAY_WRITE };
641+
const struct cred *cred = current_cred();
642+
643+
static const int oflag2acc[O_ACCMODE] = { MAY_READ, MAY_WRITE,
644+
MAY_READ | MAY_WRITE };
642645

643646
if ((oflag & O_ACCMODE) == (O_RDWR | O_WRONLY)) {
644647
dput(dentry);
@@ -652,7 +655,7 @@ static int oflag2acc[O_ACCMODE] = { MAY_READ, MAY_WRITE,
652655
return ERR_PTR(-EACCES);
653656
}
654657

655-
return dentry_open(dentry, mqueue_mnt, oflag);
658+
return dentry_open(dentry, mqueue_mnt, oflag, cred);
656659
}
657660

658661
asmlinkage long sys_mq_open(const char __user *u_name, int oflag, mode_t mode,

security/capability.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -330,7 +330,7 @@ static int cap_file_receive(struct file *file)
330330
return 0;
331331
}
332332

333-
static int cap_dentry_open(struct file *file)
333+
static int cap_dentry_open(struct file *file, const struct cred *cred)
334334
{
335335
return 0;
336336
}

security/security.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -606,9 +606,9 @@ int security_file_receive(struct file *file)
606606
return security_ops->file_receive(file);
607607
}
608608

609-
int security_dentry_open(struct file *file)
609+
int security_dentry_open(struct file *file, const struct cred *cred)
610610
{
611-
return security_ops->dentry_open(file);
611+
return security_ops->dentry_open(file, cred);
612612
}
613613

614614
int security_task_create(unsigned long clone_flags)

0 commit comments

Comments
 (0)