Skip to content

Commit e75b23f

Browse files
author
J. Bruce Fields
committed
nfsd: check d_can_lookup in fh_verify of directories
Create and other nfsd ops generally assume we can call lookup_one_len on inodes with S_IFDIR set. Al says that this assumption isn't true in general, though it should be for the filesystem objects nfsd sees. Add a check just to make sure our assumption isn't violated. Remove a couple checks for i_op->lookup in create code. Cc: Al Viro <viro@zeniv.linux.org.uk> Signed-off-by: J. Bruce Fields <bfields@redhat.com>
1 parent 12391d0 commit e75b23f

File tree

2 files changed

+10
-13
lines changed

2 files changed

+10
-13
lines changed

fs/nfsd/nfsfh.c

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -59,14 +59,20 @@ static int nfsd_acceptable(void *expv, struct dentry *dentry)
5959
* the write call).
6060
*/
6161
static inline __be32
62-
nfsd_mode_check(struct svc_rqst *rqstp, umode_t mode, umode_t requested)
62+
nfsd_mode_check(struct svc_rqst *rqstp, struct dentry *dentry,
63+
umode_t requested)
6364
{
64-
mode &= S_IFMT;
65+
umode_t mode = d_inode(dentry)->i_mode & S_IFMT;
6566

6667
if (requested == 0) /* the caller doesn't care */
6768
return nfs_ok;
68-
if (mode == requested)
69+
if (mode == requested) {
70+
if (mode == S_IFDIR && !d_can_lookup(dentry)) {
71+
WARN_ON_ONCE(1);
72+
return nfserr_notdir;
73+
}
6974
return nfs_ok;
75+
}
7076
/*
7177
* v4 has an error more specific than err_notdir which we should
7278
* return in preference to err_notdir:
@@ -340,7 +346,7 @@ fh_verify(struct svc_rqst *rqstp, struct svc_fh *fhp, umode_t type, int access)
340346
if (error)
341347
goto out;
342348

343-
error = nfsd_mode_check(rqstp, d_inode(dentry)->i_mode, type);
349+
error = nfsd_mode_check(rqstp, dentry, type);
344350
if (error)
345351
goto out;
346352

fs/nfsd/vfs.c

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1169,9 +1169,6 @@ nfsd_create(struct svc_rqst *rqstp, struct svc_fh *fhp,
11691169
dentry = fhp->fh_dentry;
11701170
dirp = d_inode(dentry);
11711171

1172-
err = nfserr_notdir;
1173-
if (!dirp->i_op->lookup)
1174-
goto out;
11751172
/*
11761173
* Check whether the response file handle has been verified yet.
11771174
* If it has, the parent directory should already be locked.
@@ -1310,12 +1307,6 @@ do_nfsd_create(struct svc_rqst *rqstp, struct svc_fh *fhp,
13101307
dentry = fhp->fh_dentry;
13111308
dirp = d_inode(dentry);
13121309

1313-
/* Get all the sanity checks out of the way before
1314-
* we lock the parent. */
1315-
err = nfserr_notdir;
1316-
if (!dirp->i_op->lookup)
1317-
goto out;
1318-
13191310
host_err = fh_want_write(fhp);
13201311
if (host_err)
13211312
goto out_nfserr;

0 commit comments

Comments
 (0)