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