* [PATCH 2/8] usb: typec: altmodes/displayport: validate count before reading Status Update VDO
2026-05-13 15:52 [PATCH 1/8] usb: typec: wcove: don't write past struct pd_message in wcove_read_rx_buffer() Greg Kroah-Hartman
@ 2026-05-13 15:52 ` Greg Kroah-Hartman
2026-05-13 15:52 ` [PATCH 3/8] usb: typec: tcpm/tcpci_maxim: validate header NDO against RX_BYTE_CNT Greg Kroah-Hartman
` (5 subsequent siblings)
6 siblings, 0 replies; 10+ messages in thread
From: Greg Kroah-Hartman @ 2026-05-13 15:52 UTC (permalink / raw)
To: linux-usb; +Cc: linux-kernel, Greg Kroah-Hartman, Heikki Krogerus, stable
A broken/malicious device can send the incorrect count for a status
update VDO, which will cause the kernel to read uninitialized stack data
and send it off elsewhere.
Fix this up by correctly verifying the count for the update object.
Assisted-by: gkh_clanker_t1000
Cc: Heikki Krogerus <heikki.krogerus@linux.intel.com>
Cc: stable <stable@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/usb/typec/altmodes/displayport.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/usb/typec/altmodes/displayport.c b/drivers/usb/typec/altmodes/displayport.c
index 35d9c3086990..263a89c5f324 100644
--- a/drivers/usb/typec/altmodes/displayport.c
+++ b/drivers/usb/typec/altmodes/displayport.c
@@ -405,6 +405,8 @@ static int dp_altmode_vdm(struct typec_altmode *alt,
dp->state = DP_STATE_EXIT_PRIME;
break;
case DP_CMD_STATUS_UPDATE:
+ if (count < 2)
+ break;
dp->data.status = *vdo;
ret = dp_altmode_status_update(dp);
break;
--
2.54.0
^ permalink raw reply related [flat|nested] 10+ messages in thread* [PATCH 3/8] usb: typec: tcpm/tcpci_maxim: validate header NDO against RX_BYTE_CNT
2026-05-13 15:52 [PATCH 1/8] usb: typec: wcove: don't write past struct pd_message in wcove_read_rx_buffer() Greg Kroah-Hartman
2026-05-13 15:52 ` [PATCH 2/8] usb: typec: altmodes/displayport: validate count before reading Status Update VDO Greg Kroah-Hartman
@ 2026-05-13 15:52 ` Greg Kroah-Hartman
2026-05-13 15:52 ` [PATCH 4/8] usb: typec: tcpm: validate VDO count in Discover Identity ACK handlers Greg Kroah-Hartman
` (4 subsequent siblings)
6 siblings, 0 replies; 10+ messages in thread
From: Greg Kroah-Hartman @ 2026-05-13 15:52 UTC (permalink / raw)
To: linux-usb
Cc: linux-kernel, Greg Kroah-Hartman, Heikki Krogerus,
André Draszik, Badhri Jagan Sridharan, Amit Sunil Dhamne,
stable
A broken/malicious port can transmit a CRC-valid frame whose header
advertises up to seven data objects but whose body carries fewer than
that. Check for this, and rightfully reject the message, instead of
reading from uninitialized stack memory.
Assisted-by: gkh_clanker_t1000
Cc: Heikki Krogerus <heikki.krogerus@linux.intel.com>
Cc: "André Draszik" <andre.draszik@linaro.org>
Cc: Badhri Jagan Sridharan <badhri@google.com>
Cc: Amit Sunil Dhamne <amitsd@google.com>
Cc: stable <stable@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/usb/typec/tcpm/tcpci_maxim_core.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/drivers/usb/typec/tcpm/tcpci_maxim_core.c b/drivers/usb/typec/tcpm/tcpci_maxim_core.c
index c0ee7e6959ed..7324139d51c8 100644
--- a/drivers/usb/typec/tcpm/tcpci_maxim_core.c
+++ b/drivers/usb/typec/tcpm/tcpci_maxim_core.c
@@ -181,6 +181,15 @@ static void process_rx(struct max_tcpci_chip *chip, u16 status)
rx_buf_ptr = rx_buf + TCPC_RECEIVE_BUFFER_RX_BYTE_BUF_OFFSET;
msg.header = cpu_to_le16(*(u16 *)rx_buf_ptr);
rx_buf_ptr = rx_buf_ptr + sizeof(msg.header);
+
+ if (count < TCPC_RECEIVE_BUFFER_RX_BYTE_BUF_OFFSET + sizeof(msg.header) +
+ pd_header_cnt_le(msg.header) * sizeof(msg.payload[0])) {
+ max_tcpci_write16(chip, TCPC_ALERT, TCPC_ALERT_RX_STATUS);
+ dev_err(chip->dev, "Invalid TCPC_RX_BYTE_CNT %d for header cnt %d\n",
+ count, pd_header_cnt_le(msg.header));
+ return;
+ }
+
for (payload_index = 0; payload_index < pd_header_cnt_le(msg.header); payload_index++,
rx_buf_ptr += sizeof(msg.payload[0]))
msg.payload[payload_index] = cpu_to_le32(*(u32 *)rx_buf_ptr);
--
2.54.0
^ permalink raw reply related [flat|nested] 10+ messages in thread* [PATCH 4/8] usb: typec: tcpm: validate VDO count in Discover Identity ACK handlers
2026-05-13 15:52 [PATCH 1/8] usb: typec: wcove: don't write past struct pd_message in wcove_read_rx_buffer() Greg Kroah-Hartman
2026-05-13 15:52 ` [PATCH 2/8] usb: typec: altmodes/displayport: validate count before reading Status Update VDO Greg Kroah-Hartman
2026-05-13 15:52 ` [PATCH 3/8] usb: typec: tcpm/tcpci_maxim: validate header NDO against RX_BYTE_CNT Greg Kroah-Hartman
@ 2026-05-13 15:52 ` Greg Kroah-Hartman
2026-05-13 15:52 ` [PATCH 5/8] usb: typec: tcpm: validate VDO count before reading Attention status VDO Greg Kroah-Hartman
` (3 subsequent siblings)
6 siblings, 0 replies; 10+ messages in thread
From: Greg Kroah-Hartman @ 2026-05-13 15:52 UTC (permalink / raw)
To: linux-usb
Cc: linux-kernel, Greg Kroah-Hartman, Badhri Jagan Sridharan,
Heikki Krogerus, stable
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: Badhri Jagan Sridharan <badhri@google.com>
Cc: Heikki Krogerus <heikki.krogerus@linux.intel.com>
Cc: stable <stable@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/usb/typec/tcpm/tcpm.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/drivers/usb/typec/tcpm/tcpm.c b/drivers/usb/typec/tcpm/tcpm.c
index 55fee96d3342..44dab6c32c33 100644
--- a/drivers/usb/typec/tcpm/tcpm.c
+++ b/drivers/usb/typec/tcpm/tcpm.c
@@ -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:
--
2.54.0
^ permalink raw reply related [flat|nested] 10+ messages in thread* [PATCH 5/8] usb: typec: tcpm: validate VDO count before reading Attention status VDO
2026-05-13 15:52 [PATCH 1/8] usb: typec: wcove: don't write past struct pd_message in wcove_read_rx_buffer() Greg Kroah-Hartman
` (2 preceding siblings ...)
2026-05-13 15:52 ` [PATCH 4/8] usb: typec: tcpm: validate VDO count in Discover Identity ACK handlers Greg Kroah-Hartman
@ 2026-05-13 15:52 ` Greg Kroah-Hartman
2026-05-13 15:52 ` [PATCH 6/8] usb: typec: tcpm: bound altmode_desc[] per iteration in svdm_consume_modes() Greg Kroah-Hartman
` (2 subsequent siblings)
6 siblings, 0 replies; 10+ messages in thread
From: Greg Kroah-Hartman @ 2026-05-13 15:52 UTC (permalink / raw)
To: linux-usb
Cc: linux-kernel, Greg Kroah-Hartman, Badhri Jagan Sridharan,
Heikki Krogerus, stable
A broken/malicious device can send the incorrect count for an attention
status VDO, which will cause the kernel to read uninitialized stack data
and send it off elsewhere.
Fix this up by correctly verifying the count for the attention object.
Assisted-by: gkh_clanker_t1000
Cc: Badhri Jagan Sridharan <badhri@google.com>
Cc: Heikki Krogerus <heikki.krogerus@linux.intel.com>
Cc: stable <stable@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/usb/typec/tcpm/tcpm.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/usb/typec/tcpm/tcpm.c b/drivers/usb/typec/tcpm/tcpm.c
index 44dab6c32c33..2cab74ed71a7 100644
--- a/drivers/usb/typec/tcpm/tcpm.c
+++ b/drivers/usb/typec/tcpm/tcpm.c
@@ -2639,6 +2639,8 @@ static void tcpm_handle_vdm_request(struct tcpm_port *port,
}
break;
case ADEV_ATTENTION:
+ if (cnt < 2)
+ break;
if (typec_altmode_attention(adev, p[1]))
tcpm_log(port, "typec_altmode_attention no port partner altmode");
break;
--
2.54.0
^ permalink raw reply related [flat|nested] 10+ messages in thread* [PATCH 6/8] usb: typec: tcpm: bound altmode_desc[] per iteration in svdm_consume_modes()
2026-05-13 15:52 [PATCH 1/8] usb: typec: wcove: don't write past struct pd_message in wcove_read_rx_buffer() Greg Kroah-Hartman
` (3 preceding siblings ...)
2026-05-13 15:52 ` [PATCH 5/8] usb: typec: tcpm: validate VDO count before reading Attention status VDO Greg Kroah-Hartman
@ 2026-05-13 15:52 ` Greg Kroah-Hartman
2026-05-13 15:52 ` [PATCH 7/8] usb: typec: ucsi: displayport: NAK DP_CMD_CONFIGURE without a payload VDO Greg Kroah-Hartman
2026-05-13 15:52 ` [PATCH 8/8] usb: typec: ucsi: validate connector number in ucsi_connector_change() Greg Kroah-Hartman
6 siblings, 0 replies; 10+ messages in thread
From: Greg Kroah-Hartman @ 2026-05-13 15:52 UTC (permalink / raw)
To: linux-usb
Cc: linux-kernel, Greg Kroah-Hartman, Badhri Jagan Sridharan,
Heikki Krogerus, stable
svdm_consume_modes() checks pmdata->altmodes against the array size once
before the loop over the count, but forgot to check the bound at every
point in the loop.
In the well-behaved SVDM discovery flow this is harmless because each of
at most SVID_DISCOVERY_MAX SVIDs contributes at most MODE_DISCOVERY_MAX
modes, exactly filling altmode_desc[ALTMODE_DISCOVERY_MAX]. But the
CMDT_RSP_ACK handler in tcpm_pd_svdm() does not correlate an incoming
ACK with any request the port actually sent. Once port->partner is set,
an unsolicited Discover Modes ACK is consumed unconditionally. A broken
or malicious port partner can therefore drive altmodes to
ALTMODE_DISCOVERY_MAX - 1 via the normal flow, and then send one extra
Discover Modes ACK with seven VDOs. Because the pre-loop check passes,
the loop could then writes up to five entries past altmode_desc[]. For
mode_data_prime the next field in struct tcpm_port is the
partner_altmode[] pointer array, which then receives partner-chosen
SVID/VDO bytes.
Move the bound check inside the loop so the array can never be indexed
past ALTMODE_DISCOVERY_MAX regardless of how many VDOs the partner
supplies or how the function was reached.
Assisted-by: gkh_clanker_t1000
Cc: Badhri Jagan Sridharan <badhri@google.com>
Cc: Heikki Krogerus <heikki.krogerus@linux.intel.com>
Cc: stable <stable@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/usb/typec/tcpm/tcpm.c | 12 ++++--------
1 file changed, 4 insertions(+), 8 deletions(-)
diff --git a/drivers/usb/typec/tcpm/tcpm.c b/drivers/usb/typec/tcpm/tcpm.c
index 2cab74ed71a7..8d904a9013fb 100644
--- a/drivers/usb/typec/tcpm/tcpm.c
+++ b/drivers/usb/typec/tcpm/tcpm.c
@@ -1992,23 +1992,19 @@ static void svdm_consume_modes(struct tcpm_port *port, const u32 *p, int cnt,
switch (rx_sop_type) {
case TCPC_TX_SOP_PRIME:
pmdata = &port->mode_data_prime;
- if (pmdata->altmodes >= ARRAY_SIZE(port->plug_prime_altmode)) {
- /* Already logged in svdm_consume_svids() */
- return;
- }
break;
case TCPC_TX_SOP:
pmdata = &port->mode_data;
- if (pmdata->altmodes >= ARRAY_SIZE(port->partner_altmode)) {
- /* Already logged in svdm_consume_svids() */
- return;
- }
break;
default:
return;
}
for (i = 1; i < cnt; i++) {
+ if (pmdata->altmodes >= ALTMODE_DISCOVERY_MAX) {
+ /* Already logged in svdm_consume_svids() */
+ return;
+ }
paltmode = &pmdata->altmode_desc[pmdata->altmodes];
memset(paltmode, 0, sizeof(*paltmode));
--
2.54.0
^ permalink raw reply related [flat|nested] 10+ messages in thread* [PATCH 7/8] usb: typec: ucsi: displayport: NAK DP_CMD_CONFIGURE without a payload VDO
2026-05-13 15:52 [PATCH 1/8] usb: typec: wcove: don't write past struct pd_message in wcove_read_rx_buffer() Greg Kroah-Hartman
` (4 preceding siblings ...)
2026-05-13 15:52 ` [PATCH 6/8] usb: typec: tcpm: bound altmode_desc[] per iteration in svdm_consume_modes() Greg Kroah-Hartman
@ 2026-05-13 15:52 ` Greg Kroah-Hartman
2026-05-13 15:52 ` [PATCH 8/8] usb: typec: ucsi: validate connector number in ucsi_connector_change() Greg Kroah-Hartman
6 siblings, 0 replies; 10+ messages in thread
From: Greg Kroah-Hartman @ 2026-05-13 15:52 UTC (permalink / raw)
To: linux-usb
Cc: linux-kernel, Greg Kroah-Hartman, Heikki Krogerus, Pooja Katiyar,
Johan Hovold, stable
ucsi_displayport_vdm() handles a DP_CMD_CONFIGURE by copying the first
payload VDO from data[], but unlike the equivalent handler in
altmodes/displayport.c it does not check that count covers a VDO beyond
the header. A header-only Configure VDM (count == 1) would read one u32
past the caller's array.
In the normal UCSI path the caller controls count, so this is hardening
for non-standard delivery paths. NAK and bail when no configuration VDO
is present, matching the generic DP altmode driver's existing guard.
Assisted-by: gkh_clanker_t1000
Cc: Heikki Krogerus <heikki.krogerus@linux.intel.com>
Cc: Pooja Katiyar <pooja.katiyar@intel.com>
Cc: Johan Hovold <johan@kernel.org>
Cc: stable <stable@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/usb/typec/ucsi/displayport.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/drivers/usb/typec/ucsi/displayport.c b/drivers/usb/typec/ucsi/displayport.c
index 8aae80b457d7..67a0991a7b76 100644
--- a/drivers/usb/typec/ucsi/displayport.c
+++ b/drivers/usb/typec/ucsi/displayport.c
@@ -240,6 +240,10 @@ static int ucsi_displayport_vdm(struct typec_altmode *alt,
dp->header |= VDO_CMDT(CMDT_RSP_ACK);
break;
case DP_CMD_CONFIGURE:
+ if (count < 2) {
+ dp->header |= VDO_CMDT(CMDT_RSP_NAK);
+ break;
+ }
dp->data.conf = *data;
if (ucsi_displayport_configure(dp)) {
dp->header |= VDO_CMDT(CMDT_RSP_NAK);
--
2.54.0
^ permalink raw reply related [flat|nested] 10+ messages in thread* [PATCH 8/8] usb: typec: ucsi: validate connector number in ucsi_connector_change()
2026-05-13 15:52 [PATCH 1/8] usb: typec: wcove: don't write past struct pd_message in wcove_read_rx_buffer() Greg Kroah-Hartman
` (5 preceding siblings ...)
2026-05-13 15:52 ` [PATCH 7/8] usb: typec: ucsi: displayport: NAK DP_CMD_CONFIGURE without a payload VDO Greg Kroah-Hartman
@ 2026-05-13 15:52 ` Greg Kroah-Hartman
2026-05-13 16:03 ` Benson Leung
2026-05-13 16:13 ` Abel Vesa
6 siblings, 2 replies; 10+ messages in thread
From: Greg Kroah-Hartman @ 2026-05-13 15:52 UTC (permalink / raw)
To: linux-usb
Cc: linux-kernel, Greg Kroah-Hartman, Heikki Krogerus, Benson Leung,
Jameson Thies, Nathan Rebello, Johan Hovold, Pooja Katiyar,
Hsin-Te Yuan, Abel Vesa, stable
The connector number in a UCSI CCI notification is a 7-bit field
supplied by the PPM. ucsi_connector_change() uses it to index the
ucsi->connector[] array without checking it against the number of
connectors the PPM reported at init time, so a buggy or malicious PPM
(EC firmware, or an I2C-attached UCSI controller on the ccg / stm32g0 /
glink transports) can drive schedule_work() on memory past the end of
the array.
Reject connector numbers that are zero or exceed cap.num_connectors
before dereferencing the array.
Assisted-by: gkh_clanker_t1000
Cc: Heikki Krogerus <heikki.krogerus@linux.intel.com>
Cc: Benson Leung <bleung@chromium.org>
Cc: Jameson Thies <jthies@google.com>
Cc: Nathan Rebello <nathan.c.rebello@gmail.com>
Cc: Johan Hovold <johan@kernel.org>
Cc: Pooja Katiyar <pooja.katiyar@intel.com>
Cc: Hsin-Te Yuan <yuanhsinte@chromium.org>
Cc: Abel Vesa <abelvesa@kernel.org>
Cc: stable <stable@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/usb/typec/ucsi/ucsi.c | 11 ++++++++++-
1 file changed, 10 insertions(+), 1 deletion(-)
diff --git a/drivers/usb/typec/ucsi/ucsi.c b/drivers/usb/typec/ucsi/ucsi.c
index 5b7ad9e99cb9..539dc706798d 100644
--- a/drivers/usb/typec/ucsi/ucsi.c
+++ b/drivers/usb/typec/ucsi/ucsi.c
@@ -1380,13 +1380,22 @@ static void ucsi_handle_connector_change(struct work_struct *work)
*/
void ucsi_connector_change(struct ucsi *ucsi, u8 num)
{
- struct ucsi_connector *con = &ucsi->connector[num - 1];
+ struct ucsi_connector *con;
if (!(ucsi->ntfy & UCSI_ENABLE_NTFY_CONNECTOR_CHANGE)) {
dev_dbg(ucsi->dev, "Early connector change event\n");
return;
}
+ if (!num || num > ucsi->cap.num_connectors) {
+ dev_warn_ratelimited(ucsi->dev,
+ "Bogus connector change on %u (max %u)\n",
+ num, ucsi->cap.num_connectors);
+ return;
+ }
+
+ con = &ucsi->connector[num - 1];
+
if (!test_and_set_bit(EVENT_PENDING, &ucsi->flags))
schedule_work(&con->work);
}
--
2.54.0
^ permalink raw reply related [flat|nested] 10+ messages in thread* Re: [PATCH 8/8] usb: typec: ucsi: validate connector number in ucsi_connector_change()
2026-05-13 15:52 ` [PATCH 8/8] usb: typec: ucsi: validate connector number in ucsi_connector_change() Greg Kroah-Hartman
@ 2026-05-13 16:03 ` Benson Leung
2026-05-13 16:13 ` Abel Vesa
1 sibling, 0 replies; 10+ messages in thread
From: Benson Leung @ 2026-05-13 16:03 UTC (permalink / raw)
To: Greg Kroah-Hartman
Cc: linux-usb, linux-kernel, Heikki Krogerus, Benson Leung,
Jameson Thies, Nathan Rebello, Johan Hovold, Pooja Katiyar,
Hsin-Te Yuan, Abel Vesa, stable
[-- Attachment #1: Type: text/plain, Size: 2280 bytes --]
On Wed, May 13, 2026 at 05:52:55PM +0200, Greg Kroah-Hartman wrote:
> The connector number in a UCSI CCI notification is a 7-bit field
> supplied by the PPM. ucsi_connector_change() uses it to index the
> ucsi->connector[] array without checking it against the number of
> connectors the PPM reported at init time, so a buggy or malicious PPM
> (EC firmware, or an I2C-attached UCSI controller on the ccg / stm32g0 /
> glink transports) can drive schedule_work() on memory past the end of
> the array.
>
> Reject connector numbers that are zero or exceed cap.num_connectors
> before dereferencing the array.
>
> Assisted-by: gkh_clanker_t1000
> Cc: Heikki Krogerus <heikki.krogerus@linux.intel.com>
> Cc: Benson Leung <bleung@chromium.org>
> Cc: Jameson Thies <jthies@google.com>
> Cc: Nathan Rebello <nathan.c.rebello@gmail.com>
> Cc: Johan Hovold <johan@kernel.org>
> Cc: Pooja Katiyar <pooja.katiyar@intel.com>
> Cc: Hsin-Te Yuan <yuanhsinte@chromium.org>
> Cc: Abel Vesa <abelvesa@kernel.org>
> Cc: stable <stable@kernel.org>
> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Reviewed-by: Benson Leung <bleung@chromium.org>
> ---
> drivers/usb/typec/ucsi/ucsi.c | 11 ++++++++++-
> 1 file changed, 10 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/usb/typec/ucsi/ucsi.c b/drivers/usb/typec/ucsi/ucsi.c
> index 5b7ad9e99cb9..539dc706798d 100644
> --- a/drivers/usb/typec/ucsi/ucsi.c
> +++ b/drivers/usb/typec/ucsi/ucsi.c
> @@ -1380,13 +1380,22 @@ static void ucsi_handle_connector_change(struct work_struct *work)
> */
> void ucsi_connector_change(struct ucsi *ucsi, u8 num)
> {
> - struct ucsi_connector *con = &ucsi->connector[num - 1];
> + struct ucsi_connector *con;
>
> if (!(ucsi->ntfy & UCSI_ENABLE_NTFY_CONNECTOR_CHANGE)) {
> dev_dbg(ucsi->dev, "Early connector change event\n");
> return;
> }
>
> + if (!num || num > ucsi->cap.num_connectors) {
> + dev_warn_ratelimited(ucsi->dev,
> + "Bogus connector change on %u (max %u)\n",
> + num, ucsi->cap.num_connectors);
> + return;
> + }
> +
> + con = &ucsi->connector[num - 1];
> +
> if (!test_and_set_bit(EVENT_PENDING, &ucsi->flags))
> schedule_work(&con->work);
> }
> --
> 2.54.0
>
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply [flat|nested] 10+ messages in thread* Re: [PATCH 8/8] usb: typec: ucsi: validate connector number in ucsi_connector_change()
2026-05-13 15:52 ` [PATCH 8/8] usb: typec: ucsi: validate connector number in ucsi_connector_change() Greg Kroah-Hartman
2026-05-13 16:03 ` Benson Leung
@ 2026-05-13 16:13 ` Abel Vesa
1 sibling, 0 replies; 10+ messages in thread
From: Abel Vesa @ 2026-05-13 16:13 UTC (permalink / raw)
To: Greg Kroah-Hartman
Cc: linux-usb, linux-kernel, Heikki Krogerus, Benson Leung,
Jameson Thies, Nathan Rebello, Johan Hovold, Pooja Katiyar,
Hsin-Te Yuan, Abel Vesa, stable
On 26-05-13 17:52:55, Greg Kroah-Hartman wrote:
> The connector number in a UCSI CCI notification is a 7-bit field
> supplied by the PPM. ucsi_connector_change() uses it to index the
> ucsi->connector[] array without checking it against the number of
> connectors the PPM reported at init time, so a buggy or malicious PPM
> (EC firmware, or an I2C-attached UCSI controller on the ccg / stm32g0 /
> glink transports) can drive schedule_work() on memory past the end of
> the array.
>
> Reject connector numbers that are zero or exceed cap.num_connectors
> before dereferencing the array.
>
> Assisted-by: gkh_clanker_t1000
> Cc: Heikki Krogerus <heikki.krogerus@linux.intel.com>
> Cc: Benson Leung <bleung@chromium.org>
> Cc: Jameson Thies <jthies@google.com>
> Cc: Nathan Rebello <nathan.c.rebello@gmail.com>
> Cc: Johan Hovold <johan@kernel.org>
> Cc: Pooja Katiyar <pooja.katiyar@intel.com>
> Cc: Hsin-Te Yuan <yuanhsinte@chromium.org>
> Cc: Abel Vesa <abelvesa@kernel.org>
> Cc: stable <stable@kernel.org>
> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Reviewed-by: Abel Vesa <abel.vesa@oss.qualcomm.com>
^ permalink raw reply [flat|nested] 10+ messages in thread