Patch "nfsd: call op_release, even when op_func returns an error" has been added to the 5.15-stable tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is a note to let you know that I've just added the patch titled

    nfsd: call op_release, even when op_func returns an error

to the 5.15-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     nfsd-call-op_release-even-when-op_func-returns-an-er.patch
and it can be found in the queue-5.15 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@xxxxxxxxxxxxxxx> know about it.



commit 39831c674abd795e639cddf07c12834e115fa2df
Author: Jeff Layton <jlayton@xxxxxxxxxx>
Date:   Mon Mar 27 06:21:37 2023 -0400

    nfsd: call op_release, even when op_func returns an error
    
    [ Upstream commit 15a8b55dbb1ba154d82627547c5761cac884d810 ]
    
    For ops with "trivial" replies, nfsd4_encode_operation will shortcut
    most of the encoding work and skip to just marshalling up the status.
    One of the things it skips is calling op_release. This could cause a
    memory leak in the layoutget codepath if there is an error at an
    inopportune time.
    
    Have the compound processing engine always call op_release, even when
    op_func sets an error in op->status. With this change, we also need
    nfsd4_block_get_device_info_scsi to set the gd_device pointer to NULL
    on error to avoid a double free.
    
    Reported-by: Zhi Li <yieli@xxxxxxxxxx>
    Link: https://bugzilla.redhat.com/show_bug.cgi?id=2181403
    Fixes: 34b1744c91cc ("nfsd4: define ->op_release for compound ops")
    Signed-off-by: Jeff Layton <jlayton@xxxxxxxxxx>
    Signed-off-by: Chuck Lever <chuck.lever@xxxxxxxxxx>

diff --git a/fs/nfsd/blocklayout.c b/fs/nfsd/blocklayout.c
index 6bb23bca154a5..835ea2ed049ee 100644
--- a/fs/nfsd/blocklayout.c
+++ b/fs/nfsd/blocklayout.c
@@ -298,6 +298,7 @@ nfsd4_block_get_device_info_scsi(struct super_block *sb,
 
 out_free_dev:
 	kfree(dev);
+	gdp->gd_device = NULL;
 	return ret;
 }
 
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index 9c9ff3bdc62a9..30c64c3f5fa05 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -5398,10 +5398,8 @@ nfsd4_encode_operation(struct nfsd4_compoundres *resp, struct nfsd4_op *op)
 	__be32 *p;
 
 	p = xdr_reserve_space(xdr, 8);
-	if (!p) {
-		WARN_ON_ONCE(1);
-		return;
-	}
+	if (!p)
+		goto release;
 	*p++ = cpu_to_be32(op->opnum);
 	post_err_offset = xdr->buf->len;
 
@@ -5416,8 +5414,6 @@ nfsd4_encode_operation(struct nfsd4_compoundres *resp, struct nfsd4_op *op)
 	op->status = encoder(resp, op->status, &op->u);
 	if (op->status)
 		trace_nfsd_compound_encode_err(rqstp, op->opnum, op->status);
-	if (opdesc && opdesc->op_release)
-		opdesc->op_release(&op->u);
 	xdr_commit_encode(xdr);
 
 	/* nfsd4_check_resp_size guarantees enough room for error status */
@@ -5458,6 +5454,9 @@ nfsd4_encode_operation(struct nfsd4_compoundres *resp, struct nfsd4_op *op)
 	}
 status:
 	*p = op->status;
+release:
+	if (opdesc && opdesc->op_release)
+		opdesc->op_release(&op->u);
 }
 
 /* 




[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux