[PATCH] scsi: qedi: bound UIO TX packet length before copying

Pengpeng Hou posted 1 patch 4 days, 7 hours ago
drivers/scsi/qedi/qedi_iscsi.c | 7 +++++++
1 file changed, 7 insertions(+)
[PATCH] scsi: qedi: bound UIO TX packet length before copying
Posted by Pengpeng Hou 4 days, 7 hours ago
qedi_data_avail() trusts the userspace-written host_tx_pkt_len field and
uses it to size an skb and memcpy() from udev->tx_pkt. qedi_alloc_uio()
lays out udev->tx_pkt and udev->rx_pkt one qedi_ll2_buf_size slot apart
in the shared LL2 buffer, but qedi_data_avail() does not currently
verify that host_tx_pkt_len stays within that TX slot.

Reject oversized host_tx_pkt_len values before allocating and copying the packet.

Fixes: ace7f46ba5fd ("scsi: qedi: Add QLogic FastLinQ offload iSCSI driver framework.")
Signed-off-by: Pengpeng Hou <pengpeng@iscas.ac.cn>
---
 drivers/scsi/qedi/qedi_iscsi.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/drivers/scsi/qedi/qedi_iscsi.c b/drivers/scsi/qedi/qedi_iscsi.c
index 6ab3a989d281..83200bd063df 100644
--- a/drivers/scsi/qedi/qedi_iscsi.c
+++ b/drivers/scsi/qedi/qedi_iscsi.c
@@ -1219,6 +1219,7 @@ static int qedi_data_avail(struct qedi_ctx *qedi, u16 vlanid)
 	struct qedi_uio_dev *udev;
 	struct qedi_uio_ctrl *uctrl;
 	struct sk_buff *skb;
+	size_t tx_slot_len;
 	u32 len;
 	int rc = 0;
 
@@ -1240,6 +1241,12 @@ static int qedi_data_avail(struct qedi_ctx *qedi, u16 vlanid)
 		return -EINVAL;
 	}
 
+	tx_slot_len = (char *)udev->rx_pkt - (char *)udev->tx_pkt;
+	if (len > tx_slot_len) {
+		QEDI_ERR(&qedi->dbg_ctx, "Invalid tx packet len %u\n", len);
+		return -EINVAL;
+	}
+
 	skb = alloc_skb(len, GFP_ATOMIC);
 	if (!skb) {
 		QEDI_ERR(&qedi->dbg_ctx, "alloc_skb failed\n");
-- 
2.50.1 (Apple Git-155)