Skip to content

Commit

Permalink
usb: typec: ucsi: Fix NULL pointer access
Browse files Browse the repository at this point in the history
Resources should be released only after all threads that utilize them
have been destroyed.
This commit ensures that resources are not released prematurely by waiting
for the associated workqueue to complete before deallocating them.

Cc: stable <stable@kernel.org>
Fixes: b9aa02c ("usb: typec: ucsi: Add polling mechanism for partner tasks like alt mode checking")
Signed-off-by: Andrei Kuchynski <akuchynski@chromium.org>
Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
Link: https://lore.kernel.org/r/20250305111739.1489003-2-akuchynski@chromium.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
  • Loading branch information
Andrei Kuchynski authored and Greg Kroah-Hartman committed Mar 6, 2025
1 parent ff71218 commit b13abcb
Showing 1 changed file with 7 additions and 6 deletions.
13 changes: 7 additions & 6 deletions drivers/usb/typec/ucsi/ucsi.c
Original file line number Diff line number Diff line change
Expand Up @@ -1825,11 +1825,11 @@ static int ucsi_init(struct ucsi *ucsi)

err_unregister:
for (con = connector; con->port; con++) {
if (con->wq)
destroy_workqueue(con->wq);
ucsi_unregister_partner(con);
ucsi_unregister_altmodes(con, UCSI_RECIPIENT_CON);
ucsi_unregister_port_psy(con);
if (con->wq)
destroy_workqueue(con->wq);

usb_power_delivery_unregister_capabilities(con->port_sink_caps);
con->port_sink_caps = NULL;
Expand Down Expand Up @@ -2013,10 +2013,6 @@ void ucsi_unregister(struct ucsi *ucsi)

for (i = 0; i < ucsi->cap.num_connectors; i++) {
cancel_work_sync(&ucsi->connector[i].work);
ucsi_unregister_partner(&ucsi->connector[i]);
ucsi_unregister_altmodes(&ucsi->connector[i],
UCSI_RECIPIENT_CON);
ucsi_unregister_port_psy(&ucsi->connector[i]);

if (ucsi->connector[i].wq) {
struct ucsi_work *uwork;
Expand All @@ -2032,6 +2028,11 @@ void ucsi_unregister(struct ucsi *ucsi)
destroy_workqueue(ucsi->connector[i].wq);
}

ucsi_unregister_partner(&ucsi->connector[i]);
ucsi_unregister_altmodes(&ucsi->connector[i],
UCSI_RECIPIENT_CON);
ucsi_unregister_port_psy(&ucsi->connector[i]);

usb_power_delivery_unregister_capabilities(ucsi->connector[i].port_sink_caps);
ucsi->connector[i].port_sink_caps = NULL;
usb_power_delivery_unregister_capabilities(ucsi->connector[i].port_source_caps);
Expand Down

0 comments on commit b13abcb

Please sign in to comment.