Skip to content

Commit

Permalink
nfsd: Make creates return EEXIST instead of EACCES
Browse files Browse the repository at this point in the history
When doing a create (mkdir/mknod) on a name, it's worth
checking the name exists first before returning EACCES in case
the directory is not writeable by the user.
This makes return values on the client more consistent
regardless of whenever the entry there is cached in the local
cache or not.
Another positive side effect is certain programs only expect
EEXIST in that case even despite POSIX allowing any valid
error to be returned.

Signed-off-by: Oleg Drokin <green@linuxhacker.ru>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
  • Loading branch information
verygreen authored and J. Bruce Fields committed Aug 4, 2016
1 parent c7995f8 commit 7eed34f
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 2 deletions.
6 changes: 5 additions & 1 deletion fs/nfsd/nfs4proc.c
Original file line number Diff line number Diff line change
Expand Up @@ -605,8 +605,12 @@ nfsd4_create(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,

fh_init(&resfh, NFS4_FHSIZE);

/*
* We just check that parent is accessible here, nfsd_* do their
* own access permission checks
*/
status = fh_verify(rqstp, &cstate->current_fh, S_IFDIR,
NFSD_MAY_CREATE);
NFSD_MAY_EXEC);
if (status)
return status;

Expand Down
11 changes: 10 additions & 1 deletion fs/nfsd/vfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -1161,7 +1161,11 @@ nfsd_create(struct svc_rqst *rqstp, struct svc_fh *fhp,
if (isdotent(fname, flen))
goto out;

err = fh_verify(rqstp, fhp, S_IFDIR, NFSD_MAY_CREATE);
/*
* Even though it is a create, first let's see if we are even allowed
* to peek inside the parent
*/
err = fh_verify(rqstp, fhp, S_IFDIR, NFSD_MAY_EXEC);
if (err)
goto out;

Expand Down Expand Up @@ -1211,6 +1215,11 @@ nfsd_create(struct svc_rqst *rqstp, struct svc_fh *fhp,
goto out;
}

/* Now let's see if we actually have permissions to create */
err = nfsd_permission(rqstp, fhp->fh_export, dentry, NFSD_MAY_CREATE);
if (err)
goto out;

if (!(iap->ia_valid & ATTR_MODE))
iap->ia_mode = 0;
iap->ia_mode = (iap->ia_mode & S_IALLUGO) | type;
Expand Down

0 comments on commit 7eed34f

Please sign in to comment.