diff mbox series

nfsd: fix NULL dereference in nfs3svc_encode_getaclres

Message ID 20210702153751.GA29685@fieldses.org (mailing list archive)
State New, archived
Headers show
Series nfsd: fix NULL dereference in nfs3svc_encode_getaclres | expand

Commit Message

J. Bruce Fields July 2, 2021, 3:37 p.m. UTC
From: "J. Bruce Fields" <bfields@redhat.com>

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>
Fixes: 20798dfe249a ("NFSD: Update the NFSv3 GETACL result encoder...")
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
---
 fs/nfsd/nfs3acl.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

Comments

Chuck Lever III July 2, 2021, 7:04 p.m. UTC | #1
> On Jul 2, 2021, at 11:37 AM, J. Bruce Fields <bfields@fieldses.org> wrote:
> 
> From: "J. Bruce Fields" <bfields@redhat.com>
> 
> 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>
> Fixes: 20798dfe249a ("NFSD: Update the NFSv3 GETACL result encoder...")
> Signed-off-by: J. Bruce Fields <bfields@redhat.com>

Reviewed-by: Chuck Lever <chuck.lever@oracle.com>


> ---
> fs/nfsd/nfs3acl.c | 3 ++-
> 1 file changed, 2 insertions(+), 1 deletion(-)
> 
> diff --git a/fs/nfsd/nfs3acl.c b/fs/nfsd/nfs3acl.c
> index a1591feeea22..5dfe7644a517 100644
> --- a/fs/nfsd/nfs3acl.c
> +++ b/fs/nfsd/nfs3acl.c
> @@ -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)
> -- 
> 2.31.1
> 

--
Chuck Lever
diff mbox series

Patch

diff --git a/fs/nfsd/nfs3acl.c b/fs/nfsd/nfs3acl.c
index a1591feeea22..5dfe7644a517 100644
--- a/fs/nfsd/nfs3acl.c
+++ b/fs/nfsd/nfs3acl.c
@@ -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)