linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Sasha Levin <sashal@kernel.org>
To: linux-kernel@vger.kernel.org, stable@vger.kernel.org
Cc: Mike Christie <michael.christie@oracle.com>,
	Lv Yunlong <lyl2019@mail.ustc.edu.cn>,
	"Martin K . Petersen" <martin.petersen@oracle.com>,
	Sasha Levin <sashal@kernel.org>,
	linux-scsi@vger.kernel.org
Subject: [PATCH AUTOSEL 5.4 02/37] scsi: be2iscsi: Fix use-after-free during IP updates
Date: Thu,  9 Sep 2021 20:21:07 -0400	[thread overview]
Message-ID: <20210910002143.175731-2-sashal@kernel.org> (raw)
In-Reply-To: <20210910002143.175731-1-sashal@kernel.org>

From: Mike Christie <michael.christie@oracle.com>

[ Upstream commit 7b0ddc1346089b62b45e688e350c9e1c3f7a3ab2 ]

This fixes a bug found by Lv Yunlong where, because beiscsi_exec_nemb_cmd()
frees memory for the be_dma_mem cmd(), we can access freed memory when
beiscsi_if_clr_ip()/beiscsi_if_set_ip()'s call to beiscsi_exec_nemb_cmd()
fails and we access the freed req. This fixes the issue by having the
caller free the cmd's memory.

Link: https://lore.kernel.org/r/20210701190840.175120-1-michael.christie@oracle.com
Reported-by: Lv Yunlong <lyl2019@mail.ustc.edu.cn>
Signed-off-by: Mike Christie <michael.christie@oracle.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/scsi/be2iscsi/be_mgmt.c | 84 ++++++++++++++++++---------------
 1 file changed, 45 insertions(+), 39 deletions(-)

diff --git a/drivers/scsi/be2iscsi/be_mgmt.c b/drivers/scsi/be2iscsi/be_mgmt.c
index d4febaadfaa3..6797ff249588 100644
--- a/drivers/scsi/be2iscsi/be_mgmt.c
+++ b/drivers/scsi/be2iscsi/be_mgmt.c
@@ -234,8 +234,7 @@ static int beiscsi_exec_nemb_cmd(struct beiscsi_hba *phba,
 	wrb = alloc_mcc_wrb(phba, &tag);
 	if (!wrb) {
 		mutex_unlock(&ctrl->mbox_lock);
-		rc = -ENOMEM;
-		goto free_cmd;
+		return -ENOMEM;
 	}
 
 	sge = nonembedded_sgl(wrb);
@@ -268,24 +267,6 @@ static int beiscsi_exec_nemb_cmd(struct beiscsi_hba *phba,
 	/* copy the response, if any */
 	if (resp_buf)
 		memcpy(resp_buf, nonemb_cmd->va, resp_buf_len);
-	/**
-	 * This is special case of NTWK_GET_IF_INFO where the size of
-	 * response is not known. beiscsi_if_get_info checks the return
-	 * value to free DMA buffer.
-	 */
-	if (rc == -EAGAIN)
-		return rc;
-
-	/**
-	 * If FW is busy that is driver timed out, DMA buffer is saved with
-	 * the tag, only when the cmd completes this buffer is freed.
-	 */
-	if (rc == -EBUSY)
-		return rc;
-
-free_cmd:
-	dma_free_coherent(&ctrl->pdev->dev, nonemb_cmd->size,
-			    nonemb_cmd->va, nonemb_cmd->dma);
 	return rc;
 }
 
@@ -308,6 +289,19 @@ static int beiscsi_prep_nemb_cmd(struct beiscsi_hba *phba,
 	return 0;
 }
 
+static void beiscsi_free_nemb_cmd(struct beiscsi_hba *phba,
+				  struct be_dma_mem *cmd, int rc)
+{
+	/*
+	 * If FW is busy the DMA buffer is saved with the tag. When the cmd
+	 * completes this buffer is freed.
+	 */
+	if (rc == -EBUSY)
+		return;
+
+	dma_free_coherent(&phba->ctrl.pdev->dev, cmd->size, cmd->va, cmd->dma);
+}
+
 static void __beiscsi_eq_delay_compl(struct beiscsi_hba *phba, unsigned int tag)
 {
 	struct be_dma_mem *tag_mem;
@@ -343,8 +337,16 @@ int beiscsi_modify_eq_delay(struct beiscsi_hba *phba,
 				cpu_to_le32(set_eqd[i].delay_multiplier);
 	}
 
-	return beiscsi_exec_nemb_cmd(phba, &nonemb_cmd,
-				     __beiscsi_eq_delay_compl, NULL, 0);
+	rc = beiscsi_exec_nemb_cmd(phba, &nonemb_cmd, __beiscsi_eq_delay_compl,
+				   NULL, 0);
+	if (rc) {
+		/*
+		 * Only free on failure. Async cmds are handled like -EBUSY
+		 * where it's handled for us.
+		 */
+		beiscsi_free_nemb_cmd(phba, &nonemb_cmd, rc);
+	}
+	return rc;
 }
 
 /**
@@ -371,6 +373,7 @@ int beiscsi_get_initiator_name(struct beiscsi_hba *phba, char *name, bool cfg)
 		req->hdr.version = 1;
 	rc = beiscsi_exec_nemb_cmd(phba, &nonemb_cmd, NULL,
 				   &resp, sizeof(resp));
+	beiscsi_free_nemb_cmd(phba, &nonemb_cmd, rc);
 	if (rc) {
 		beiscsi_log(phba, KERN_ERR,
 			    BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
@@ -448,7 +451,9 @@ static int beiscsi_if_mod_gw(struct beiscsi_hba *phba,
 	req->ip_addr.ip_type = ip_type;
 	memcpy(req->ip_addr.addr, gw,
 	       (ip_type < BEISCSI_IP_TYPE_V6) ? IP_V4_LEN : IP_V6_LEN);
-	return beiscsi_exec_nemb_cmd(phba, &nonemb_cmd, NULL, NULL, 0);
+	rt_val = beiscsi_exec_nemb_cmd(phba, &nonemb_cmd, NULL, NULL, 0);
+	beiscsi_free_nemb_cmd(phba, &nonemb_cmd, rt_val);
+	return rt_val;
 }
 
 int beiscsi_if_set_gw(struct beiscsi_hba *phba, u32 ip_type, u8 *gw)
@@ -498,8 +503,10 @@ int beiscsi_if_get_gw(struct beiscsi_hba *phba, u32 ip_type,
 	req = nonemb_cmd.va;
 	req->ip_type = ip_type;
 
-	return beiscsi_exec_nemb_cmd(phba, &nonemb_cmd, NULL,
-				     resp, sizeof(*resp));
+	rc = beiscsi_exec_nemb_cmd(phba, &nonemb_cmd, NULL, resp,
+				   sizeof(*resp));
+	beiscsi_free_nemb_cmd(phba, &nonemb_cmd, rc);
+	return rc;
 }
 
 static int
@@ -536,6 +543,7 @@ beiscsi_if_clr_ip(struct beiscsi_hba *phba,
 			    "BG_%d : failed to clear IP: rc %d status %d\n",
 			    rc, req->ip_params.ip_record.status);
 	}
+	beiscsi_free_nemb_cmd(phba, &nonemb_cmd, rc);
 	return rc;
 }
 
@@ -580,6 +588,7 @@ beiscsi_if_set_ip(struct beiscsi_hba *phba, u8 *ip,
 		if (req->ip_params.ip_record.status)
 			rc = -EINVAL;
 	}
+	beiscsi_free_nemb_cmd(phba, &nonemb_cmd, rc);
 	return rc;
 }
 
@@ -607,6 +616,7 @@ int beiscsi_if_en_static(struct beiscsi_hba *phba, u32 ip_type,
 		reldhcp->interface_hndl = phba->interface_handle;
 		reldhcp->ip_type = ip_type;
 		rc = beiscsi_exec_nemb_cmd(phba, &nonemb_cmd, NULL, NULL, 0);
+		beiscsi_free_nemb_cmd(phba, &nonemb_cmd, rc);
 		if (rc < 0) {
 			beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
 				    "BG_%d : failed to release existing DHCP: %d\n",
@@ -688,7 +698,7 @@ int beiscsi_if_en_dhcp(struct beiscsi_hba *phba, u32 ip_type)
 	dhcpreq->interface_hndl = phba->interface_handle;
 	dhcpreq->ip_type = ip_type;
 	rc = beiscsi_exec_nemb_cmd(phba, &nonemb_cmd, NULL, NULL, 0);
-
+	beiscsi_free_nemb_cmd(phba, &nonemb_cmd, rc);
 exit:
 	kfree(if_info);
 	return rc;
@@ -761,11 +771,8 @@ int beiscsi_if_get_info(struct beiscsi_hba *phba, int ip_type,
 				    BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG,
 				    "BG_%d : Memory Allocation Failure\n");
 
-				/* Free the DMA memory for the IOCTL issuing */
-				dma_free_coherent(&phba->ctrl.pdev->dev,
-						    nonemb_cmd.size,
-						    nonemb_cmd.va,
-						    nonemb_cmd.dma);
+				beiscsi_free_nemb_cmd(phba, &nonemb_cmd,
+						      -ENOMEM);
 				return -ENOMEM;
 		}
 
@@ -780,15 +787,13 @@ int beiscsi_if_get_info(struct beiscsi_hba *phba, int ip_type,
 				      nonemb_cmd.va)->actual_resp_len;
 			ioctl_size += sizeof(struct be_cmd_req_hdr);
 
-			/* Free the previous allocated DMA memory */
-			dma_free_coherent(&phba->ctrl.pdev->dev, nonemb_cmd.size,
-					    nonemb_cmd.va,
-					    nonemb_cmd.dma);
-
+			beiscsi_free_nemb_cmd(phba, &nonemb_cmd, rc);
 			/* Free the virtual memory */
 			kfree(*if_info);
-		} else
+		} else {
+			beiscsi_free_nemb_cmd(phba, &nonemb_cmd, rc);
 			break;
+		}
 	} while (true);
 	return rc;
 }
@@ -805,8 +810,9 @@ int mgmt_get_nic_conf(struct beiscsi_hba *phba,
 	if (rc)
 		return rc;
 
-	return beiscsi_exec_nemb_cmd(phba, &nonemb_cmd, NULL,
-				     nic, sizeof(*nic));
+	rc = beiscsi_exec_nemb_cmd(phba, &nonemb_cmd, NULL, nic, sizeof(*nic));
+	beiscsi_free_nemb_cmd(phba, &nonemb_cmd, rc);
+	return rc;
 }
 
 static void beiscsi_boot_process_compl(struct beiscsi_hba *phba,
-- 
2.30.2


  reply	other threads:[~2021-09-10  0:59 UTC|newest]

Thread overview: 38+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-09-10  0:21 [PATCH AUTOSEL 5.4 01/37] clk: rockchip: rk3036: fix up the sclk_sfc parent error Sasha Levin
2021-09-10  0:21 ` Sasha Levin [this message]
2021-09-10  0:21 ` [PATCH AUTOSEL 5.4 03/37] scsi: lpfc: Fix NVMe support reporting in log message Sasha Levin
2021-09-10  0:21 ` [PATCH AUTOSEL 5.4 04/37] f2fs: Revert "f2fs: Fix indefinite loop in f2fs_gc() v1" Sasha Levin
2021-09-10  0:21 ` [PATCH AUTOSEL 5.4 05/37] scsi: smartpqi: Fix ISR accessing uninitialized data Sasha Levin
2021-09-10  0:21 ` [PATCH AUTOSEL 5.4 06/37] scsi: lpfc: Fix cq_id truncation in rq create Sasha Levin
2021-09-10  0:21 ` [PATCH AUTOSEL 5.4 07/37] clk: mediatek: Fix asymmetrical PLL enable and disable control Sasha Levin
2021-09-10  0:21 ` [PATCH AUTOSEL 5.4 08/37] HID: usbhid: free raw_report buffers in usbhid_stop Sasha Levin
2021-09-10  0:21 ` [PATCH AUTOSEL 5.4 09/37] f2fs: fix to force keeping write barrier for strict fsync mode Sasha Levin
2021-09-10  0:21 ` [PATCH AUTOSEL 5.4 10/37] f2fs: fix min_seq_blocks can not make sense in some scenes Sasha Levin
2021-09-10  0:21 ` [PATCH AUTOSEL 5.4 11/37] scsi: ufs: Verify UIC locking requirements at runtime Sasha Levin
2021-09-10  0:21 ` [PATCH AUTOSEL 5.4 12/37] powerpc: make the install target not depend on any build artifact Sasha Levin
2021-09-10  0:21 ` [PATCH AUTOSEL 5.4 13/37] KVM: PPC: Book3S HV: XICS: Fix mapping of passthrough interrupts Sasha Levin
2021-09-10  0:21 ` [PATCH AUTOSEL 5.4 14/37] jbd2: fix portability problems caused by unaligned accesses Sasha Levin
2021-09-10  0:21 ` [PATCH AUTOSEL 5.4 15/37] scsi: qla2xxx: Fix port type info Sasha Levin
2021-09-10  0:21 ` [PATCH AUTOSEL 5.4 16/37] scsi: qla2xxx: Fix NPIV create erroneous error Sasha Levin
2021-09-10  0:21 ` [PATCH AUTOSEL 5.4 17/37] ovl: skip checking lower file's i_writecount on truncate Sasha Levin
2021-09-10  0:21 ` [PATCH AUTOSEL 5.4 18/37] scsi: target: pscsi: Fix possible null-pointer dereference in pscsi_complete_cmd() Sasha Levin
2021-09-10  0:21 ` [PATCH AUTOSEL 5.4 19/37] fs: dlm: fix return -EINTR on recovery stopped Sasha Levin
2021-09-10  0:21 ` [PATCH AUTOSEL 5.4 20/37] HID: sony: Fix more ShanWan clone gamepads to not rumble when plugged in Sasha Levin
2021-09-10  0:21 ` [PATCH AUTOSEL 5.4 21/37] MIPS: mscc: ocelot: disable all switch ports by default Sasha Levin
2021-09-10  0:21 ` [PATCH AUTOSEL 5.4 22/37] MIPS: mscc: ocelot: mark the phy-mode for internal PHY ports Sasha Levin
2021-09-12 10:14   ` Vladimir Oltean
2021-09-10  0:21 ` [PATCH AUTOSEL 5.4 23/37] scsi: core: Fix missing FORCE for scsi_devinfo_tbl.c build rule Sasha Levin
2021-09-10  0:21 ` [PATCH AUTOSEL 5.4 24/37] powerpc/32: indirect function call use bctrl rather than blrl in ret_from_kernel_thread Sasha Levin
2021-09-10  0:21 ` [PATCH AUTOSEL 5.4 25/37] powerpc/booke: Avoid link stack corruption in several places Sasha Levin
2021-09-10  0:21 ` [PATCH AUTOSEL 5.4 26/37] KVM: PPC: Book3S HV: Initialise vcpu MSR with MSR_ME Sasha Levin
2021-09-10  0:21 ` [PATCH AUTOSEL 5.4 27/37] KVM: PPC: Book3S HV P9: Fixes for TM softpatch interrupt NIP Sasha Levin
2021-09-10  0:21 ` [PATCH AUTOSEL 5.4 28/37] KVM: PPC: Book3S HV Nested: Fix TM softpatch HFAC interrupt emulation Sasha Levin
2021-09-10  0:21 ` [PATCH AUTOSEL 5.4 29/37] RDMA/core/sa_query: Retry SA queries Sasha Levin
2021-09-10  0:21 ` [PATCH AUTOSEL 5.4 30/37] platform/x86: dell-smbios-wmi: Avoid false-positive memcpy() warning Sasha Levin
2021-09-10  0:21 ` [PATCH AUTOSEL 5.4 31/37] clk: zynqmp: Fix a memory leak Sasha Levin
2021-09-10  0:21 ` [PATCH AUTOSEL 5.4 32/37] ext4: if zeroout fails fall back to splitting the extent node Sasha Levin
2021-09-10  0:21 ` [PATCH AUTOSEL 5.4 33/37] ext4: Make sure quota files are not grabbed accidentally Sasha Levin
2021-09-10  0:21 ` [PATCH AUTOSEL 5.4 34/37] xen: remove stray preempt_disable() from PV AP startup code Sasha Levin
2021-09-10  0:21 ` [PATCH AUTOSEL 5.4 35/37] checkkconfigsymbols.py: Fix the '--ignore' option Sasha Levin
2021-09-10  0:21 ` [PATCH AUTOSEL 5.4 36/37] ocfs2: quota_local: fix possible uninitialized-variable access in ocfs2_local_read_info() Sasha Levin
2021-09-10  0:21 ` [PATCH AUTOSEL 5.4 37/37] ocfs2: ocfs2_downconvert_lock failure results in deadlock Sasha Levin

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20210910002143.175731-2-sashal@kernel.org \
    --to=sashal@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-scsi@vger.kernel.org \
    --cc=lyl2019@mail.ustc.edu.cn \
    --cc=martin.petersen@oracle.com \
    --cc=michael.christie@oracle.com \
    --cc=stable@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).