]> git.hungrycats.org Git - linux/commitdiff
nfsd4: fix READ permission checking
authorJ. Bruce Fields <bfields@redhat.com>
Fri, 3 Apr 2015 21:19:41 +0000 (17:19 -0400)
committerSasha Levin <sasha.levin@oracle.com>
Sun, 17 May 2015 23:12:25 +0000 (19:12 -0400)
[ Upstream commit 6e4891dc289cd191d46ab7ba1dcb29646644f9ca ]

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>
Signed-off-by: Sasha Levin <sasha.levin@oracle.com>
fs/nfsd/nfs4xdr.c

index 2a77603d7cfd62d806f4d70f78e0405d5ecfe83b..6abe96593225a58af197f8eb240ebd6daa2705a4 100644 (file)
@@ -3229,6 +3229,7 @@ nfsd4_encode_read(struct nfsd4_compoundres *resp, __be32 nfserr,
        unsigned long maxcount;
        struct xdr_stream *xdr = &resp->xdr;
        struct file *file = read->rd_filp;
+       struct svc_fh *fhp = read->rd_fhp;
        int starting_len = xdr->buf->len;
        struct raparms *ra;
        __be32 *p;
@@ -3252,12 +3253,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, 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,
                                                &file, &ra);
-               if (err)
-                       goto err_truncate;
-       }
+       if (err)
+               goto err_truncate;
 
        if (file->f_op->splice_read && resp->rqstp->rq_splice_ok)
                err = nfsd4_encode_splice_read(resp, read, file, maxcount);