This is a note to let you know that I've just added the patch titled usb: ucsi: Fix ucsi->connector race to the 6.2-stable tree which can be found at: http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary The filename of the patch is: usb-ucsi-fix-ucsi-connector-race.patch and it can be found in the queue-6.2 subdirectory. If you, or anyone else, feels it should not be added to the stable tree, please let <stable@xxxxxxxxxxxxxxx> know about it. >From 0482c34ec6f8557e06cd0f8e2d0e20e8ede6a22c Mon Sep 17 00:00:00 2001 From: Hans de Goede <hdegoede@xxxxxxxxxx> Date: Wed, 8 Mar 2023 16:42:43 +0100 Subject: usb: ucsi: Fix ucsi->connector race From: Hans de Goede <hdegoede@xxxxxxxxxx> commit 0482c34ec6f8557e06cd0f8e2d0e20e8ede6a22c upstream. ucsi_init() which runs from a workqueue sets ucsi->connector and on an error will clear it again. ucsi->connector gets dereferenced by ucsi_resume(), this checks for ucsi->connector being NULL in case ucsi_init() has not finished yet; or in case ucsi_init() has failed. ucsi_init() setting ucsi->connector and then clearing it again on an error creates a race where the check in ucsi_resume() may pass, only to have ucsi->connector free-ed underneath it when ucsi_init() hits an error. Fix this race by making ucsi_init() store the connector array in a local variable and only assign it to ucsi->connector on success. Fixes: bdc62f2bae8f ("usb: typec: ucsi: Simplified registration and I/O API") Cc: stable@xxxxxxxxxxxxxxx Reviewed-by: Heikki Krogerus <heikki.krogerus@xxxxxxxxxxxxxxx> Signed-off-by: Hans de Goede <hdegoede@xxxxxxxxxx> Link: https://lore.kernel.org/r/20230308154244.722337-3-hdegoede@xxxxxxxxxx Signed-off-by: Joakim Tjernlund <joakim.tjernlund@xxxxxxxxxxxx> Signed-off-by: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx> --- drivers/usb/typec/ucsi/ucsi.c | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) --- a/drivers/usb/typec/ucsi/ucsi.c +++ b/drivers/usb/typec/ucsi/ucsi.c @@ -1039,9 +1039,8 @@ static struct fwnode_handle *ucsi_find_f return NULL; } -static int ucsi_register_port(struct ucsi *ucsi, int index) +static int ucsi_register_port(struct ucsi *ucsi, struct ucsi_connector *con) { - struct ucsi_connector *con = &ucsi->connector[index]; struct typec_capability *cap = &con->typec_cap; enum typec_accessory *accessory = cap->accessory; enum usb_role u_role = USB_ROLE_NONE; @@ -1062,7 +1061,6 @@ static int ucsi_register_port(struct ucs init_completion(&con->complete); mutex_init(&con->lock); INIT_LIST_HEAD(&con->partner_tasks); - con->num = index + 1; con->ucsi = ucsi; cap->fwnode = ucsi_find_fwnode(con); @@ -1204,7 +1202,7 @@ out_unlock: */ static int ucsi_init(struct ucsi *ucsi) { - struct ucsi_connector *con; + struct ucsi_connector *con, *connector; u64 command, ntfy; int ret; int i; @@ -1235,16 +1233,16 @@ static int ucsi_init(struct ucsi *ucsi) } /* Allocate the connectors. Released in ucsi_unregister() */ - ucsi->connector = kcalloc(ucsi->cap.num_connectors + 1, - sizeof(*ucsi->connector), GFP_KERNEL); - if (!ucsi->connector) { + connector = kcalloc(ucsi->cap.num_connectors + 1, sizeof(*connector), GFP_KERNEL); + if (!connector) { ret = -ENOMEM; goto err_reset; } /* Register all connectors */ for (i = 0; i < ucsi->cap.num_connectors; i++) { - ret = ucsi_register_port(ucsi, i); + connector[i].num = i + 1; + ret = ucsi_register_port(ucsi, &connector[i]); if (ret) goto err_unregister; } @@ -1256,11 +1254,12 @@ static int ucsi_init(struct ucsi *ucsi) if (ret < 0) goto err_unregister; + ucsi->connector = connector; ucsi->ntfy = ntfy; return 0; err_unregister: - for (con = ucsi->connector; con->port; con++) { + for (con = connector; con->port; con++) { ucsi_unregister_partner(con); ucsi_unregister_altmodes(con, UCSI_RECIPIENT_CON); ucsi_unregister_port_psy(con); @@ -1269,10 +1268,7 @@ err_unregister: typec_unregister_port(con->port); con->port = NULL; } - - kfree(ucsi->connector); - ucsi->connector = NULL; - + kfree(connector); err_reset: memset(&ucsi->cap, 0, sizeof(ucsi->cap)); ucsi_reset_ppm(ucsi); Patches currently in stable-queue which might be from hdegoede@xxxxxxxxxx are queue-6.2/acpi-x86-introduce-an-acpi_quirk_skip_gpio_event_han.patch queue-6.2/platform-x86-think-lmi-add-missing-type-attribute.patch queue-6.2/input-focaltech-use-explicitly-signed-char-type.patch queue-6.2/input-i8042-add-quirk-for-fujitsu-lifebook-a574-h.patch queue-6.2/drm-nouveau-kms-fix-backlight-registration.patch queue-6.2/platform-x86-ideapad-laptop-stop-sending-key_touchpad_toggle.patch queue-6.2/platform-x86-think-lmi-use-correct-possible_values-d.patch queue-6.2/acpi-x86-add-skip-i2c-clients-quirk-for-acer-iconia-.patch queue-6.2/usb-ucsi-fix-ucsi-connector-race.patch queue-6.2/acpi-x86-add-skip-i2c-clients-quirk-for-lenovo-yoga-.patch queue-6.2/platform-x86-think-lmi-add-possible_values-for-think.patch queue-6.2/input-goodix-add-lenovo-yoga-book-x90f-to-nine_bytes_report-dmi-table.patch queue-6.2/platform-x86-intel-pmc-alder-lake-pch-slp_s0_residen.patch queue-6.2/platform-surface-aggregator-add-missing-fwnode_handl.patch queue-6.2/platform-x86-think-lmi-only-display-possible_values-.patch