From: Greg Kroah-Hartman Date: Mon, 3 Apr 2023 13:33:09 +0000 (+0200) Subject: 6.2-stable patches X-Git-Tag: v4.14.312~12 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=807bc41323eb2f015d22b410472c4d991b79a771;p=thirdparty%2Fkernel%2Fstable-queue.git 6.2-stable patches added patches: usb-ucsi-fix-ucsi-connector-race.patch --- diff --git a/queue-6.2/series b/queue-6.2/series index 9ca36ec2467..f95987aec8a 100644 --- a/queue-6.2/series +++ b/queue-6.2/series @@ -178,6 +178,7 @@ kvm-arm64-pmu-don-t-save-pmcr_el0.-c-p-for-the-vcpu.patch kvm-arm64-retry-fault-if-vma_lookup-results-become-invalid.patch kvm-arm64-disable-interrupts-while-walking-userspace-pts.patch kvm-arm64-check-for-kvm_vma_mte_allowed-in-the-critical-section.patch +usb-ucsi-fix-ucsi-connector-race.patch libbpf-fix-btf-to-c-converter-s-padding-logic.patch selftests-bpf-add-few-corner-cases-to-test-padding-h.patch libbpf-fix-btf_dump-s-packed-struct-determination.patch diff --git a/queue-6.2/usb-ucsi-fix-ucsi-connector-race.patch b/queue-6.2/usb-ucsi-fix-ucsi-connector-race.patch new file mode 100644 index 00000000000..022b6bd5fda --- /dev/null +++ b/queue-6.2/usb-ucsi-fix-ucsi-connector-race.patch @@ -0,0 +1,112 @@ +From 0482c34ec6f8557e06cd0f8e2d0e20e8ede6a22c Mon Sep 17 00:00:00 2001 +From: Hans de Goede +Date: Wed, 8 Mar 2023 16:42:43 +0100 +Subject: usb: ucsi: Fix ucsi->connector race + +From: Hans de Goede + +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@vger.kernel.org +Reviewed-by: Heikki Krogerus +Signed-off-by: Hans de Goede +Link: https://lore.kernel.org/r/20230308154244.722337-3-hdegoede@redhat.com +Signed-off-by: Joakim Tjernlund +Signed-off-by: Greg Kroah-Hartman +--- + 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);