aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfsd/nfs4xdr.c
diff options
context:
space:
mode:
authorJ. Bruce Fields <bfields@redhat.com>2015-04-03 17:19:41 -0400
committerJ. Bruce Fields <bfields@redhat.com>2015-04-21 16:16:01 -0400
commit6e4891dc289cd191d46ab7ba1dcb29646644f9ca (patch)
tree9b99fa6fa8fd1ab4dcc571ad4125c7be2fece33a /fs/nfsd/nfs4xdr.c
parent980608fb50aea34993ba956b71cd4602aa42b14b (diff)
nfsd4: fix READ permission checking
In the case we already have a struct file (derived from a stateid), we still need to do permission-checking; otherwise an unauthorized user could gain access to a file by sniffing or guessing somebody else's stateid. Cc: stable@vger.kernel.org Fixes: dc97618ddda9 "nfsd4: separate splice and readv cases" Signed-off-by: J. Bruce Fields <bfields@redhat.com>
Diffstat (limited to 'fs/nfsd/nfs4xdr.c')
-rw-r--r--fs/nfsd/nfs4xdr.c12
1 files changed, 8 insertions, 4 deletions
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index cea6c529434f..a45032ce7b80 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -3422,6 +3422,7 @@ nfsd4_encode_read(struct nfsd4_compoundres *resp, __be32 nfserr,
3422 unsigned long maxcount; 3422 unsigned long maxcount;
3423 struct xdr_stream *xdr = &resp->xdr; 3423 struct xdr_stream *xdr = &resp->xdr;
3424 struct file *file = read->rd_filp; 3424 struct file *file = read->rd_filp;
3425 struct svc_fh *fhp = read->rd_fhp;
3425 int starting_len = xdr->buf->len; 3426 int starting_len = xdr->buf->len;
3426 struct raparms *ra; 3427 struct raparms *ra;
3427 __be32 *p; 3428 __be32 *p;
@@ -3445,12 +3446,15 @@ nfsd4_encode_read(struct nfsd4_compoundres *resp, __be32 nfserr,
3445 maxcount = min_t(unsigned long, maxcount, (xdr->buf->buflen - xdr->buf->len)); 3446 maxcount = min_t(unsigned long, maxcount, (xdr->buf->buflen - xdr->buf->len));
3446 maxcount = min_t(unsigned long, maxcount, read->rd_length); 3447 maxcount = min_t(unsigned long, maxcount, read->rd_length);
3447 3448
3448 if (!read->rd_filp) { 3449 if (read->rd_filp)
3450 err = nfsd_permission(resp->rqstp, fhp->fh_export,
3451 fhp->fh_dentry,
3452 NFSD_MAY_READ|NFSD_MAY_OWNER_OVERRIDE);
3453 else
3449 err = nfsd_get_tmp_read_open(resp->rqstp, read->rd_fhp, 3454 err = nfsd_get_tmp_read_open(resp->rqstp, read->rd_fhp,
3450 &file, &ra); 3455 &file, &ra);
3451 if (err) 3456 if (err)
3452 goto err_truncate; 3457 goto err_truncate;
3453 }
3454 3458
3455 if (file->f_op->splice_read && test_bit(RQ_SPLICE_OK, &resp->rqstp->rq_flags)) 3459 if (file->f_op->splice_read && test_bit(RQ_SPLICE_OK, &resp->rqstp->rq_flags))
3456 err = nfsd4_encode_splice_read(resp, read, file, maxcount); 3460 err = nfsd4_encode_splice_read(resp, read, file, maxcount);