nfsd: fix NULL dereference in nfs3svc_encode_getaclres
authorJ. Bruce Fields <bfields@redhat.com>
Fri, 2 Jul 2021 00:06:56 +0000 (20:06 -0400)
committerJ. Bruce Fields <bfields@redhat.com>
Wed, 7 Jul 2021 00:14:44 +0000 (20:14 -0400)
In error cases the dentry may be NULL.

Before 20798dfe249a, the encoder also checked dentry and
d_really_is_positive(dentry), but that looks like overkill to me--zero
status should be enough to guarantee a positive dentry.

This isn't the first time we've seen an error-case NULL dereference
hidden in the initialization of a local variable in an xdr encoder.  But
I went back through the other recent rewrites and didn't spot any
similar bugs.

Reported-by: JianHong Yin <jiyin@redhat.com>
Reviewed-by: Chuck Lever III <chuck.lever@oracle.com>
Fixes: 20798dfe249a ("NFSD: Update the NFSv3 GETACL result encoder...")
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
fs/nfsd/nfs3acl.c

index a1591feeea22ce9b087959d738af534f79e7a58a..5dfe7644a51722bd6fe6fd89679e3530af9a9b5e 100644 (file)
@@ -172,7 +172,7 @@ static int nfs3svc_encode_getaclres(struct svc_rqst *rqstp, __be32 *p)
        struct nfsd3_getaclres *resp = rqstp->rq_resp;
        struct dentry *dentry = resp->fh.fh_dentry;
        struct kvec *head = rqstp->rq_res.head;
-       struct inode *inode = d_inode(dentry);
+       struct inode *inode;
        unsigned int base;
        int n;
        int w;
@@ -181,6 +181,7 @@ static int nfs3svc_encode_getaclres(struct svc_rqst *rqstp, __be32 *p)
                return 0;
        switch (resp->status) {
        case nfs_ok:
+               inode = d_inode(dentry);
                if (!svcxdr_encode_post_op_attr(rqstp, xdr, &resp->fh))
                        return 0;
                if (xdr_stream_encode_u32(xdr, resp->mask) < 0)