scsi: iscsi: Verify lengths on passthrough PDUs
authorChris Leech <cleech@redhat.com>
Wed, 24 Feb 2021 05:39:01 +0000 (21:39 -0800)
committerMartin K. Petersen <martin.petersen@oracle.com>
Fri, 5 Mar 2021 01:09:51 +0000 (20:09 -0500)
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>
drivers/scsi/scsi_transport_iscsi.c

index c1eff85..91074fd 100644 (file)
@@ -3624,6 +3624,7 @@ iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, uint32_t *group)
 {
        int err = 0;
        u32 portid;
+       u32 pdu_len;
        struct iscsi_uevent *ev = nlmsg_data(nlh);
        struct iscsi_transport *transport = NULL;
        struct iscsi_internal *priv;
@@ -3766,6 +3767,14 @@ iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, uint32_t *group)
                        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);