Re: [PATCH v2] usb: typec: tipd: fix uninitialized typec_partner_desc on stack
"Pandey, Radhey Shyam" <[email protected]>
| Newsgroups | org.kernel.vger.linux-usb,org.kernel.vger.linux-kernel,org.kernel.vger.stable |
|---|---|
| Message-ID | <[email protected]> |
On 8/12/2026 2:58 PM, Heikki Krogerus wrote:
> On Fri, Aug 07, 2026 at 11:16:58PM +0530, Radhey Shyam Pandey wrote:
>> tps6598x_connect() and cd321x_update_work() pass a stack-allocated
>> typec_partner_desc to typec_register_partner() after initializing only
>> usb_pd, accessory and identity.
>>
>> typec_register_partner() copies attach and deattach from the descriptor
>> into the partner. With those fields left unset, garbage function pointers
>> may be stored and later invoked from typec_partner_link_device() when a USB
>> device is linked to the port. Uninitialized pd_revision and usb_capability
>> similarly leak stack data through partner sysfs.
>>
>> Zero-initialize the descriptor so optional callbacks remain NULL and the
>> remaining fields are zero.
>>
>> Assisted-by: claude-mythos-preview-high
>> Fixes: 82432bbfb9e8 ("usb: typec: tipd: Handle mode transitions for CD321x")
>> Fixes: 0a4c005bd171 ("usb: typec: driver for TI TPS6598x USB Power Delivery controllers")
>> Cc: [email protected]
>> Signed-off-by: Radhey Shyam Pandey <[email protected]>
>
> Reviewed-by: Heikki Krogerus <[email protected]>
>
Thanks for the review. To simplify stable backporting, I split the
patch and posted it as v3. Since the patch was split, I did not carry
over the Reviewed-by tag in v3. Please have a look at it.
https://lore.kernel.org/all/[email protected]
>> ---
>> Changes for v2:
>> - Add Assisted-by tag.
>> - Remove explicit indentity=NULL
>>
>> AI code scanning identified this issue; the possible call graph is shown below.
>>
>> USB-C plug event (IRQ)
>> tps6598x_interrupt()
>> tps6598x_handle_plug_event()
>> tps6598x_connect()
>> struct typec_partner_desc desc; /* bug: attach/deattach unset */
>> desc.usb_pd / .accessory / .identity = ...
>> typec_register_partner(port, &desc) /* class.c */
>> partner->attach = desc->attach; /* copy stack garbage */
>> partner->deattach = desc->deattach;
>> [if port->usb2_dev || port->usb3_dev already set]
>> typec_partner_link_device(partner, dev)
>> if (partner->attach)
>> partner->attach(partner, dev) /* indirect call via bad ptr */
>> ---
>> drivers/usb/typec/tipd/core.c | 6 ++----
>> 1 file changed, 2 insertions(+), 4 deletions(-)
>>
>> diff --git a/drivers/usb/typec/tipd/core.c b/drivers/usb/typec/tipd/core.c
>> index 522f56742aa9..d99a55063e34 100644
>> --- a/drivers/usb/typec/tipd/core.c
>> +++ b/drivers/usb/typec/tipd/core.c
>> @@ -344,7 +344,7 @@ static void tps6598x_set_data_role(struct tps6598x *tps,
>>
>> static int tps6598x_connect(struct tps6598x *tps, u32 status)
>> {
>> - struct typec_partner_desc desc;
>> + struct typec_partner_desc desc = { };
>> enum typec_pwr_opmode mode;
>> int ret;
>>
>> @@ -355,7 +355,6 @@ static int tps6598x_connect(struct tps6598x *tps, u32 status)
>>
>> desc.usb_pd = mode == TYPEC_PWR_MODE_PD;
>> desc.accessory = TYPEC_ACCESSORY_NONE; /* XXX: handle accessories */
>> - desc.identity = NULL;
>>
>> if (desc.usb_pd) {
>> ret = tps6598x_read_partner_identity(tps);
>> @@ -841,11 +840,10 @@ static void cd321x_update_work(struct work_struct *work)
>>
>> /* Set up partner if we were previously disconnected (or changed). */
>> if (!tps->partner) {
>> - struct typec_partner_desc desc;
>> + struct typec_partner_desc desc = { };
>>
>> desc.usb_pd = is_pd;
>> desc.accessory = TYPEC_ACCESSORY_NONE; /* XXX: handle accessories */
>> - desc.identity = NULL;
>>
>> if (desc.usb_pd)
>> desc.identity = &st.partner_identity;
>>
>> base-commit: ea2bff00da89d7767d677bb68470130ba96f4928
>> --
>> 2.44.4
>