Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6e4891dc authored by J. Bruce Fields's avatar J. Bruce Fields
Browse files

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: dc97618d "nfsd4: separate splice and readv cases"
Signed-off-by: default avatarJ. Bruce Fields <bfields@redhat.com>
parent 980608fb
Loading
Loading
Loading
Loading
+8 −4
Original line number Original line Diff line number Diff line
@@ -3422,6 +3422,7 @@ nfsd4_encode_read(struct nfsd4_compoundres *resp, __be32 nfserr,
	unsigned long maxcount;
	unsigned long maxcount;
	struct xdr_stream *xdr = &resp->xdr;
	struct xdr_stream *xdr = &resp->xdr;
	struct file *file = read->rd_filp;
	struct file *file = read->rd_filp;
	struct svc_fh *fhp = read->rd_fhp;
	int starting_len = xdr->buf->len;
	int starting_len = xdr->buf->len;
	struct raparms *ra;
	struct raparms *ra;
	__be32 *p;
	__be32 *p;
@@ -3445,12 +3446,15 @@ nfsd4_encode_read(struct nfsd4_compoundres *resp, __be32 nfserr,
	maxcount = min_t(unsigned long, maxcount, (xdr->buf->buflen - xdr->buf->len));
	maxcount = min_t(unsigned long, maxcount, (xdr->buf->buflen - xdr->buf->len));
	maxcount = min_t(unsigned long, maxcount, read->rd_length);
	maxcount = min_t(unsigned long, maxcount, read->rd_length);


	if (!read->rd_filp) {
	if (read->rd_filp)
		err = nfsd_permission(resp->rqstp, fhp->fh_export,
				fhp->fh_dentry,
				NFSD_MAY_READ|NFSD_MAY_OWNER_OVERRIDE);
	else
		err = nfsd_get_tmp_read_open(resp->rqstp, read->rd_fhp,
		err = nfsd_get_tmp_read_open(resp->rqstp, read->rd_fhp,
						&file, &ra);
						&file, &ra);
	if (err)
	if (err)
		goto err_truncate;
		goto err_truncate;
	}


	if (file->f_op->splice_read && test_bit(RQ_SPLICE_OK, &resp->rqstp->rq_flags))
	if (file->f_op->splice_read && test_bit(RQ_SPLICE_OK, &resp->rqstp->rq_flags))
		err = nfsd4_encode_splice_read(resp, read, file, maxcount);
		err = nfsd4_encode_splice_read(resp, read, file, maxcount);