| From f9dbdf97a5bd92b1a49cee3d591b55b11fd7a6d5 Mon Sep 17 00:00:00 2001 |
| From: Chris Leech <cleech@redhat.com> |
| Date: Tue, 23 Feb 2021 21:39:01 -0800 |
| Subject: scsi: iscsi: Verify lengths on passthrough PDUs |
| |
| From: Chris Leech <cleech@redhat.com> |
| |
| commit f9dbdf97a5bd92b1a49cee3d591b55b11fd7a6d5 upstream. |
| |
| Open-iSCSI sends passthrough PDUs over netlink, but the kernel should be |
| verifying that the provided PDU header and data lengths fall within the |
| netlink message to prevent accessing beyond that in memory. |
| |
| Cc: stable@vger.kernel.org |
| Reported-by: Adam Nichols <adam@grimm-co.com> |
| Reviewed-by: Lee Duncan <lduncan@suse.com> |
| Reviewed-by: Mike Christie <michael.christie@oracle.com> |
| Signed-off-by: Chris Leech <cleech@redhat.com> |
| Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| drivers/scsi/scsi_transport_iscsi.c | 9 +++++++++ |
| 1 file changed, 9 insertions(+) |
| |
| --- a/drivers/scsi/scsi_transport_iscsi.c |
| +++ b/drivers/scsi/scsi_transport_iscsi.c |
| @@ -3627,6 +3627,7 @@ iscsi_if_recv_msg(struct sk_buff *skb, s |
| { |
| int err = 0; |
| u32 portid; |
| + u32 pdu_len; |
| struct iscsi_uevent *ev = nlmsg_data(nlh); |
| struct iscsi_transport *transport = NULL; |
| struct iscsi_internal *priv; |
| @@ -3769,6 +3770,14 @@ iscsi_if_recv_msg(struct sk_buff *skb, s |
| err = -EINVAL; |
| break; |
| case ISCSI_UEVENT_SEND_PDU: |
| + pdu_len = nlh->nlmsg_len - sizeof(*nlh) - sizeof(*ev); |
| + |
| + if ((ev->u.send_pdu.hdr_size > pdu_len) || |
| + (ev->u.send_pdu.data_size > (pdu_len - ev->u.send_pdu.hdr_size))) { |
| + err = -EINVAL; |
| + break; |
| + } |
| + |
| conn = iscsi_conn_lookup(ev->u.send_pdu.sid, ev->u.send_pdu.cid); |
| if (conn) { |
| mutex_lock(&conn_mutex); |