1
From: Andreas Gruenbacher <agruen@suse.de>
2
Subject: Never pass a NULL nameidata to vfs_create()
4
Create a nameidata2 struct in nfsd and mqueue so that vfs_create does
5
need to conditionally pass the vfsmnt.
7
Signed-off-by: Andreas Gruenbacher <agruen@suse.de>
8
Signed-off-by: John Johansen <jjohansen@suse.de>
12
fs/nfsd/vfs.c | 42 +++++++++++++++++++++++++-----------------
13
ipc/mqueue.c | 7 ++++++-
14
3 files changed, 32 insertions(+), 19 deletions(-)
18
@@ -1532,7 +1532,7 @@ int vfs_create(struct inode *dir, struct
19
return -EACCES; /* shouldn't it be ENOSYS? */
22
- error = security_inode_create(dir, dentry, nd ? nd->mnt : NULL, mode);
23
+ error = security_inode_create(dir, dentry, nd->mnt, mode);
29
@@ -1121,7 +1121,8 @@ nfsd_create(struct svc_rqst *rqstp, stru
30
char *fname, int flen, struct iattr *iap,
31
int type, dev_t rdev, struct svc_fh *resfhp)
33
- struct dentry *dentry, *dchild = NULL;
34
+ struct nameidata2 nd;
35
+ struct dentry *dchild = NULL;
36
struct svc_export *exp;
39
@@ -1138,9 +1139,11 @@ nfsd_create(struct svc_rqst *rqstp, stru
43
- dentry = fhp->fh_dentry;
44
+ nd.dentry = fhp->fh_dentry;
46
- dirp = dentry->d_inode;
47
+ nd.mnt = exp->ex_mnt;
49
+ dirp = nd.dentry->d_inode;
52
if(!dirp->i_op || !dirp->i_op->lookup)
53
@@ -1152,7 +1155,7 @@ nfsd_create(struct svc_rqst *rqstp, stru
54
if (!resfhp->fh_dentry) {
55
/* called from nfsd_proc_mkdir, or possibly nfsd3_proc_create */
56
fh_lock_nested(fhp, I_MUTEX_PARENT);
57
- dchild = lookup_one_len(fname, dentry, flen);
58
+ dchild = lookup_one_len(fname, nd.dentry, flen);
59
host_err = PTR_ERR(dchild);
62
@@ -1166,8 +1169,8 @@ nfsd_create(struct svc_rqst *rqstp, stru
63
/* not actually possible */
65
"nfsd_create: parent %s/%s not locked!\n",
66
- dentry->d_parent->d_name.name,
67
- dentry->d_name.name);
68
+ nd.dentry->d_parent->d_name.name,
69
+ nd.dentry->d_name.name);
73
@@ -1178,7 +1181,7 @@ nfsd_create(struct svc_rqst *rqstp, stru
75
if (dchild->d_inode) {
76
dprintk("nfsd_create: dentry %s/%s not negative!\n",
77
- dentry->d_name.name, dchild->d_name.name);
78
+ nd.dentry->d_name.name, dchild->d_name.name);
82
@@ -1192,7 +1195,7 @@ nfsd_create(struct svc_rqst *rqstp, stru
86
- host_err = vfs_create(dirp, dchild, iap->ia_mode, NULL);
87
+ host_err = vfs_create(nd.dentry->d_inode, dchild, iap->ia_mode, &nd);
90
host_err = vfs_mkdir(dirp, dchild, exp->ex_mnt, iap->ia_mode);
91
@@ -1212,7 +1215,7 @@ nfsd_create(struct svc_rqst *rqstp, stru
95
- err = nfserrno(nfsd_sync_dir(dentry));
96
+ err = nfserrno(nfsd_sync_dir(nd.dentry));
97
write_inode_now(dchild->d_inode, 1);
100
@@ -1252,7 +1255,9 @@ nfsd_create_v3(struct svc_rqst *rqstp, s
101
struct svc_fh *resfhp, int createmode, u32 *verifier,
102
int *truncp, int *created)
104
- struct dentry *dentry, *dchild = NULL;
105
+ struct nameidata2 nd;
106
+ struct dentry *dchild = NULL;
107
+ struct svc_export *exp;
111
@@ -1270,8 +1275,11 @@ nfsd_create_v3(struct svc_rqst *rqstp, s
115
- dentry = fhp->fh_dentry;
116
- dirp = dentry->d_inode;
117
+ nd.dentry = fhp->fh_dentry;
118
+ exp = fhp->fh_export;
119
+ nd.mnt = exp->ex_mnt;
121
+ dirp = nd.dentry->d_inode;
123
/* Get all the sanity checks out of the way before
124
* we lock the parent. */
125
@@ -1283,12 +1291,12 @@ nfsd_create_v3(struct svc_rqst *rqstp, s
127
* Compose the response file handle.
129
- dchild = lookup_one_len(fname, dentry, flen);
130
+ dchild = lookup_one_len(fname, nd.dentry, flen);
131
host_err = PTR_ERR(dchild);
135
- err = fh_compose(resfhp, fhp->fh_export, dchild, fhp);
136
+ err = fh_compose(resfhp, exp, dchild, fhp);
140
@@ -1334,14 +1342,14 @@ nfsd_create_v3(struct svc_rqst *rqstp, s
144
- host_err = vfs_create(dirp, dchild, iap->ia_mode, NULL);
145
+ host_err = vfs_create(nd.dentry->d_inode, dchild, iap->ia_mode, &nd);
151
- if (EX_ISSYNC(fhp->fh_export)) {
152
- err = nfserrno(nfsd_sync_dir(dentry));
153
+ if (EX_ISSYNC(exp)) {
154
+ err = nfserrno(nfsd_sync_dir(nd.dentry));
155
/* setattr will sync the child (or not) */
160
@@ -602,9 +602,14 @@ static int mq_attr_ok(struct mq_attr *at
161
static struct file *do_create(struct dentry *dir, struct dentry *dentry,
162
int oflag, mode_t mode, struct mq_attr __user *u_attr)
164
+ struct nameidata2 nd;
169
+ nd.mnt = NULL; /* Not a mounted filesystem */
174
if (copy_from_user(&attr, u_attr, sizeof(attr)))
175
@@ -617,7 +622,7 @@ static struct file *do_create(struct den
178
mode &= ~current->fs->umask;
179
- ret = vfs_create(dir->d_inode, dentry, mode, NULL);
180
+ ret = vfs_create(dir->d_inode, dentry, mode, &nd);
181
dentry->d_fsdata = NULL;