From: Greg Kroah-Hartman Date: Tue, 29 Apr 2025 07:42:28 +0000 (+0200) Subject: 6.12-stable patches X-Git-Tag: v5.4.293~35 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=4629ae5c0f64edf6f0cef60b9a1d1e361616fe14;p=thirdparty%2Fkernel%2Fstable-queue.git 6.12-stable patches added patches: usb-typec-class-fix-null-pointer-access.patch --- diff --git a/queue-6.12/series b/queue-6.12/series index 3eb9dea9af..0b9df51da7 100644 --- a/queue-6.12/series +++ b/queue-6.12/series @@ -256,3 +256,4 @@ selftests-bpf-fix-bpf_map_redirect-call-for-cpu-map-test.patch selftests-bpf-make-xdp_cpumap_attach-keep-redirect-prog-attached.patch selftests-bpf-check-program-redirect-in-xdp_cpumap_attach.patch selftests-bpf-adjust-data-size-to-have-eth_hlen.patch +usb-typec-class-fix-null-pointer-access.patch diff --git a/queue-6.12/usb-typec-class-fix-null-pointer-access.patch b/queue-6.12/usb-typec-class-fix-null-pointer-access.patch new file mode 100644 index 0000000000..0b573dedf4 --- /dev/null +++ b/queue-6.12/usb-typec-class-fix-null-pointer-access.patch @@ -0,0 +1,118 @@ +From ec27386de23a511008c53aa2f3434ad180a3ca9a Mon Sep 17 00:00:00 2001 +From: Andrei Kuchynski +Date: Fri, 21 Mar 2025 14:37:26 +0000 +Subject: usb: typec: class: Fix NULL pointer access + +From: Andrei Kuchynski + +commit ec27386de23a511008c53aa2f3434ad180a3ca9a upstream. + +Concurrent calls to typec_partner_unlink_device can lead to a NULL pointer +dereference. This patch adds a mutex to protect USB device pointers and +prevent this issue. The same mutex protects both the device pointers and +the partner device registration. + +Cc: stable@vger.kernel.org +Fixes: 59de2a56d127 ("usb: typec: Link enumerated USB devices with Type-C partner") +Signed-off-by: Andrei Kuchynski +Reviewed-by: Benson Leung +Reviewed-by: Heikki Krogerus +Link: https://lore.kernel.org/r/20250321143728.4092417-2-akuchynski@chromium.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/typec/class.c | 15 +++++++++++++-- + drivers/usb/typec/class.h | 1 + + 2 files changed, 14 insertions(+), 2 deletions(-) + +--- a/drivers/usb/typec/class.c ++++ b/drivers/usb/typec/class.c +@@ -932,6 +932,7 @@ struct typec_partner *typec_register_par + partner->dev.type = &typec_partner_dev_type; + dev_set_name(&partner->dev, "%s-partner", dev_name(&port->dev)); + ++ mutex_lock(&port->partner_link_lock); + ret = device_register(&partner->dev); + if (ret) { + dev_err(&port->dev, "failed to register partner (%d)\n", ret); +@@ -943,6 +944,7 @@ struct typec_partner *typec_register_par + typec_partner_link_device(partner, port->usb2_dev); + if (port->usb3_dev) + typec_partner_link_device(partner, port->usb3_dev); ++ mutex_unlock(&port->partner_link_lock); + + return partner; + } +@@ -963,12 +965,14 @@ void typec_unregister_partner(struct typ + + port = to_typec_port(partner->dev.parent); + ++ mutex_lock(&port->partner_link_lock); + if (port->usb2_dev) + typec_partner_unlink_device(partner, port->usb2_dev); + if (port->usb3_dev) + typec_partner_unlink_device(partner, port->usb3_dev); + + device_unregister(&partner->dev); ++ mutex_unlock(&port->partner_link_lock); + } + EXPORT_SYMBOL_GPL(typec_unregister_partner); + +@@ -1862,25 +1866,30 @@ static struct typec_partner *typec_get_p + static void typec_partner_attach(struct typec_connector *con, struct device *dev) + { + struct typec_port *port = container_of(con, struct typec_port, con); +- struct typec_partner *partner = typec_get_partner(port); ++ struct typec_partner *partner; + struct usb_device *udev = to_usb_device(dev); + ++ mutex_lock(&port->partner_link_lock); + if (udev->speed < USB_SPEED_SUPER) + port->usb2_dev = dev; + else + port->usb3_dev = dev; + ++ partner = typec_get_partner(port); + if (partner) { + typec_partner_link_device(partner, dev); + put_device(&partner->dev); + } ++ mutex_unlock(&port->partner_link_lock); + } + + static void typec_partner_deattach(struct typec_connector *con, struct device *dev) + { + struct typec_port *port = container_of(con, struct typec_port, con); +- struct typec_partner *partner = typec_get_partner(port); ++ struct typec_partner *partner; + ++ mutex_lock(&port->partner_link_lock); ++ partner = typec_get_partner(port); + if (partner) { + typec_partner_unlink_device(partner, dev); + put_device(&partner->dev); +@@ -1890,6 +1899,7 @@ static void typec_partner_deattach(struc + port->usb2_dev = NULL; + else if (port->usb3_dev == dev) + port->usb3_dev = NULL; ++ mutex_unlock(&port->partner_link_lock); + } + + /** +@@ -2425,6 +2435,7 @@ struct typec_port *typec_register_port(s + + ida_init(&port->mode_ids); + mutex_init(&port->port_type_lock); ++ mutex_init(&port->partner_link_lock); + + port->id = id; + port->ops = cap->ops; +--- a/drivers/usb/typec/class.h ++++ b/drivers/usb/typec/class.h +@@ -56,6 +56,7 @@ struct typec_port { + enum typec_pwr_opmode pwr_opmode; + enum typec_port_type port_type; + struct mutex port_type_lock; ++ struct mutex partner_link_lock; + + enum typec_orientation orientation; + struct typec_switch *sw;