Lee Duncan 71d447
From: Chris Leech <cleech@redhat.com>
Lee Duncan 71d447
Date: Tue, 23 Feb 2021 21:39:01 -0800
Lee Duncan 71d447
Subject: scsi: iscsi: Verify lengths on passthrough PDUs
Lee Duncan 71d447
Git-commit: f9dbdf97a5bd92b1a49cee3d591b55b11fd7a6d5
Lee Duncan da2d10
References: CVE-2021-27365 bsc#1182715
Lee Duncan 71d447
Patch-mainline: v5.12-rc2
Lee Duncan 71d447
Lee Duncan 71d447
Open-iSCSI sends passthrough PDUs over netlink, but the kernel should be
Lee Duncan 71d447
verifying that the provided PDU header and data lengths fall within the
Lee Duncan 71d447
netlink message to prevent accessing beyond that in memory.
Lee Duncan 71d447
Lee Duncan 71d447
Cc: stable@vger.kernel.org
Lee Duncan 71d447
Reported-by: Adam Nichols <adam@grimm-co.com>
Lee Duncan 71d447
Reviewed-by: Lee Duncan <lduncan@suse.com>
Lee Duncan 71d447
Reviewed-by: Mike Christie <michael.christie@oracle.com>
Lee Duncan 71d447
Signed-off-by: Chris Leech <cleech@redhat.com>
Lee Duncan 71d447
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Lee Duncan 71d447
Acked-by: Lee Duncan <lduncan@suse.com>
Lee Duncan 71d447
---
Lee Duncan 71d447
 drivers/scsi/scsi_transport_iscsi.c |    9 +++++++++
Lee Duncan 71d447
 1 file changed, 9 insertions(+)
Lee Duncan 71d447
Lee Duncan 71d447
--- a/drivers/scsi/scsi_transport_iscsi.c
Lee Duncan 71d447
+++ b/drivers/scsi/scsi_transport_iscsi.c
Lee Duncan 71d447
@@ -3555,6 +3555,7 @@ iscsi_if_recv_msg(struct sk_buff *skb, s
Lee Duncan 71d447
 {
Lee Duncan 71d447
 	int err = 0;
Lee Duncan 71d447
 	u32 portid;
Lee Duncan 71d447
+	u32 pdu_len;
Lee Duncan 71d447
 	struct iscsi_uevent *ev = nlmsg_data(nlh);
Lee Duncan 71d447
 	struct iscsi_transport *transport = NULL;
Lee Duncan 71d447
 	struct iscsi_internal *priv;
Lee Duncan 71d447
@@ -3670,6 +3671,14 @@ iscsi_if_recv_msg(struct sk_buff *skb, s
Lee Duncan 71d447
 			err = -EINVAL;
Lee Duncan 71d447
 		break;
Lee Duncan 71d447
 	case ISCSI_UEVENT_SEND_PDU:
Lee Duncan 71d447
+		pdu_len = nlh->nlmsg_len - sizeof(*nlh) - sizeof(*ev);
Lee Duncan 71d447
+
Lee Duncan 71d447
+		if ((ev->u.send_pdu.hdr_size > pdu_len) ||
Lee Duncan 71d447
+		    (ev->u.send_pdu.data_size > (pdu_len - ev->u.send_pdu.hdr_size))) {
Lee Duncan 71d447
+			err = -EINVAL;
Lee Duncan 71d447
+			break;
Lee Duncan 71d447
+		}
Lee Duncan 71d447
+
Lee Duncan 71d447
 		conn = iscsi_conn_lookup(ev->u.send_pdu.sid, ev->u.send_pdu.cid);
Lee Duncan 71d447
 		if (conn)
Lee Duncan 71d447
 			ev->r.retcode =	transport->send_pdu(conn,