aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfsd/vfs.c
diff options
context:
space:
mode:
authorzhengbin <zhengbin13@huawei.com>2018-11-30 03:04:25 -0500
committerJ. Bruce Fields <bfields@redhat.com>2018-12-04 20:48:07 -0500
commit255fbca65137e25b12bced18ec9a014dc77ecda0 (patch)
tree51884812c0e497b5b409ed4ede85ece15aa94a50 /fs/nfsd/vfs.c
parent4ecd55ea074217473f94cfee21bb72864d39f8d7 (diff)
nfsd: Return EPERM, not EACCES, in some SETATTR cases
As the man(2) page for utime/utimes states, EPERM is returned when the second parameter of utime or utimes is not NULL, the caller's effective UID does not match the owner of the file, and the caller is not privileged. However, in a NFS directory mounted from knfsd, it will return EACCES (from nfsd_setattr-> fh_verify->nfsd_permission). This patch fixes that. Signed-off-by: zhengbin <zhengbin13@huawei.com> Signed-off-by: J. Bruce Fields <bfields@redhat.com>
Diffstat (limited to 'fs/nfsd/vfs.c')
-rw-r--r--fs/nfsd/vfs.c17
1 files changed, 15 insertions, 2 deletions
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
index eb67098117b4..9824e32b2f23 100644
--- a/fs/nfsd/vfs.c
+++ b/fs/nfsd/vfs.c
@@ -396,10 +396,23 @@ nfsd_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp, struct iattr *iap,
396 bool get_write_count; 396 bool get_write_count;
397 bool size_change = (iap->ia_valid & ATTR_SIZE); 397 bool size_change = (iap->ia_valid & ATTR_SIZE);
398 398
399 if (iap->ia_valid & (ATTR_ATIME | ATTR_MTIME | ATTR_SIZE)) 399 if (iap->ia_valid & ATTR_SIZE) {
400 accmode |= NFSD_MAY_WRITE|NFSD_MAY_OWNER_OVERRIDE; 400 accmode |= NFSD_MAY_WRITE|NFSD_MAY_OWNER_OVERRIDE;
401 if (iap->ia_valid & ATTR_SIZE)
402 ftype = S_IFREG; 401 ftype = S_IFREG;
402 }
403
404 /*
405 * If utimes(2) and friends are called with times not NULL, we should
406 * not set NFSD_MAY_WRITE bit. Otherwise fh_verify->nfsd_permission
407 * will return EACCESS, when the caller's effective UID does not match
408 * the owner of the file, and the caller is not privileged. In this
409 * situation, we should return EPERM(notify_change will return this).
410 */
411 if (iap->ia_valid & (ATTR_ATIME | ATTR_MTIME)) {
412 accmode |= NFSD_MAY_OWNER_OVERRIDE;
413 if (!(iap->ia_valid & (ATTR_ATIME_SET | ATTR_MTIME_SET)))
414 accmode |= NFSD_MAY_WRITE;
415 }
403 416
404 /* Callers that do fh_verify should do the fh_want_write: */ 417 /* Callers that do fh_verify should do the fh_want_write: */
405 get_write_count = !fhp->fh_dentry; 418 get_write_count = !fhp->fh_dentry;