]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
usb: typec: tcpm: validate VDO count in Discover Identity ACK handlers
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 13 May 2026 15:52:51 +0000 (17:52 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 19 May 2026 10:25:49 +0000 (12:25 +0200)
Properly validate the count passed from a device when calling
svdm_consume_identity() or svdm_consume_identity_sop_prime() as the
device-controlled value could index off of the static arrays, which
could leak data.

Assisted-by: gkh_clanker_t1000
Cc: Heikki Krogerus <heikki.krogerus@linux.intel.com>
Cc: stable <stable@kernel.org>
Reviewed-by: Badhri Jagan Sridharan <badhri@google.com>
Link: https://patch.msgid.link/2026051350-plated-salute-0efe@gregkh
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/usb/typec/tcpm/tcpm.c

index 55fee96d3342add8db4641e1cd4331a73579bb7a..44dab6c32c33600a445c7b17507420388f52a51b 100644 (file)
@@ -1855,6 +1855,9 @@ static void svdm_consume_identity(struct tcpm_port *port, const u32 *p, int cnt)
        u32 vdo = p[VDO_INDEX_IDH];
        u32 product = p[VDO_INDEX_PRODUCT];
 
+       if (cnt <= VDO_INDEX_PRODUCT)
+               return;
+
        memset(&port->mode_data, 0, sizeof(port->mode_data));
 
        port->partner_ident.id_header = vdo;
@@ -1875,6 +1878,9 @@ static void svdm_consume_identity_sop_prime(struct tcpm_port *port, const u32 *p
        u32 product = p[VDO_INDEX_PRODUCT];
        int svdm_version;
 
+       if (cnt <= VDO_INDEX_CABLE_1)
+               return;
+
        /*
         * Attempt to consume identity only if cable currently is not set
         */
@@ -1898,7 +1904,7 @@ static void svdm_consume_identity_sop_prime(struct tcpm_port *port, const u32 *p
        switch (port->negotiated_rev_prime) {
        case PD_REV30:
                port->cable_desc.pd_revision = 0x0300;
-               if (port->cable_desc.active)
+               if (port->cable_desc.active && cnt > VDO_INDEX_CABLE_2)
                        port->cable_ident.vdo[1] = p[VDO_INDEX_CABLE_2];
                break;
        case PD_REV20: