From: Greg Kroah-Hartman Date: Mon, 20 Oct 2025 08:46:55 +0000 (+0200) Subject: 6.17-stable patches X-Git-Tag: v6.6.114~31 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=5e30c95cadc4b450b7ad1fddad36dbee41c403e9;p=thirdparty%2Fkernel%2Fstable-queue.git 6.17-stable patches added patches: usb-gadget-f_acm-refactor-bind-path-to-use-__free.patch usb-gadget-f_ecm-refactor-bind-path-to-use-__free.patch usb-gadget-f_ncm-refactor-bind-path-to-use-__free.patch --- diff --git a/queue-6.17/series b/queue-6.17/series index df69ba3bf1..2204bc893e 100644 --- a/queue-6.17/series +++ b/queue-6.17/series @@ -51,3 +51,6 @@ media-nxp-imx8-isi-m2m-fix-streaming-cleanup-on-release.patch usb-gadget-store-endpoint-pointer-in-usb_request.patch usb-gadget-introduce-free_usb_request-helper.patch usb-gadget-f_rndis-refactor-bind-path-to-use-__free.patch +usb-gadget-f_acm-refactor-bind-path-to-use-__free.patch +usb-gadget-f_ecm-refactor-bind-path-to-use-__free.patch +usb-gadget-f_ncm-refactor-bind-path-to-use-__free.patch diff --git a/queue-6.17/usb-gadget-f_acm-refactor-bind-path-to-use-__free.patch b/queue-6.17/usb-gadget-f_acm-refactor-bind-path-to-use-__free.patch new file mode 100644 index 0000000000..3d693cb1f6 --- /dev/null +++ b/queue-6.17/usb-gadget-f_acm-refactor-bind-path-to-use-__free.patch @@ -0,0 +1,173 @@ +From stable+bounces-187738-greg=kroah.com@vger.kernel.org Sat Oct 18 02:17:57 2025 +From: Sasha Levin +Date: Fri, 17 Oct 2025 20:17:48 -0400 +Subject: usb: gadget: f_acm: Refactor bind path to use __free() +To: stable@vger.kernel.org +Cc: Kuen-Han Tsai , stable@kernel.org, Greg Kroah-Hartman , Sasha Levin +Message-ID: <20251018001748.76008-3-sashal@kernel.org> + +From: Kuen-Han Tsai + +[ Upstream commit 47b2116e54b4a854600341487e8b55249e926324 ] + +After an bind/unbind cycle, the acm->notify_req is left stale. If a +subsequent bind fails, the unified error label attempts to free this +stale request, leading to a NULL pointer dereference when accessing +ep->ops->free_request. + +Refactor the error handling in the bind path to use the __free() +automatic cleanup mechanism. + +Unable to handle kernel NULL pointer dereference at virtual address 0000000000000020 +Call trace: + usb_ep_free_request+0x2c/0xec + gs_free_req+0x30/0x44 + acm_bind+0x1b8/0x1f4 + usb_add_function+0xcc/0x1f0 + configfs_composite_bind+0x468/0x588 + gadget_bind_driver+0x104/0x270 + really_probe+0x190/0x374 + __driver_probe_device+0xa0/0x12c + driver_probe_device+0x3c/0x218 + __device_attach_driver+0x14c/0x188 + bus_for_each_drv+0x10c/0x168 + __device_attach+0xfc/0x198 + device_initial_probe+0x14/0x24 + bus_probe_device+0x94/0x11c + device_add+0x268/0x48c + usb_add_gadget+0x198/0x28c + dwc3_gadget_init+0x700/0x858 + __dwc3_set_mode+0x3cc/0x664 + process_scheduled_works+0x1d8/0x488 + worker_thread+0x244/0x334 + kthread+0x114/0x1bc + ret_from_fork+0x10/0x20 + +Fixes: 1f1ba11b6494 ("usb gadget: issue notifications from ACM function") +Cc: stable@kernel.org +Signed-off-by: Kuen-Han Tsai +Link: https://lore.kernel.org/r/20250916-ready-v1-4-4997bf277548@google.com +Signed-off-by: Greg Kroah-Hartman +Link: https://lore.kernel.org/r/20250916-ready-v1-4-4997bf277548@google.com +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/gadget/function/f_acm.c | 42 ++++++++++++++++-------------------- + 1 file changed, 19 insertions(+), 23 deletions(-) + +--- a/drivers/usb/gadget/function/f_acm.c ++++ b/drivers/usb/gadget/function/f_acm.c +@@ -11,12 +11,15 @@ + + /* #define VERBOSE_DEBUG */ + ++#include + #include + #include + #include + #include + #include + ++#include ++ + #include "u_serial.h" + + +@@ -613,6 +616,7 @@ acm_bind(struct usb_configuration *c, st + struct usb_string *us; + int status; + struct usb_ep *ep; ++ struct usb_request *request __free(free_usb_request) = NULL; + + /* REVISIT might want instance-specific strings to help + * distinguish instances ... +@@ -630,7 +634,7 @@ acm_bind(struct usb_configuration *c, st + /* allocate instance-specific interface IDs, and patch descriptors */ + status = usb_interface_id(c, f); + if (status < 0) +- goto fail; ++ return status; + acm->ctrl_id = status; + acm_iad_descriptor.bFirstInterface = status; + +@@ -639,43 +643,41 @@ acm_bind(struct usb_configuration *c, st + + status = usb_interface_id(c, f); + if (status < 0) +- goto fail; ++ return status; + acm->data_id = status; + + acm_data_interface_desc.bInterfaceNumber = status; + acm_union_desc.bSlaveInterface0 = status; + acm_call_mgmt_descriptor.bDataInterface = status; + +- status = -ENODEV; +- + /* allocate instance-specific endpoints */ + ep = usb_ep_autoconfig(cdev->gadget, &acm_fs_in_desc); + if (!ep) +- goto fail; ++ return -ENODEV; + acm->port.in = ep; + + ep = usb_ep_autoconfig(cdev->gadget, &acm_fs_out_desc); + if (!ep) +- goto fail; ++ return -ENODEV; + acm->port.out = ep; + + ep = usb_ep_autoconfig(cdev->gadget, &acm_fs_notify_desc); + if (!ep) +- goto fail; ++ return -ENODEV; + acm->notify = ep; + + acm_iad_descriptor.bFunctionProtocol = acm->bInterfaceProtocol; + acm_control_interface_desc.bInterfaceProtocol = acm->bInterfaceProtocol; + + /* allocate notification */ +- acm->notify_req = gs_alloc_req(ep, +- sizeof(struct usb_cdc_notification) + 2, +- GFP_KERNEL); +- if (!acm->notify_req) +- goto fail; ++ request = gs_alloc_req(ep, ++ sizeof(struct usb_cdc_notification) + 2, ++ GFP_KERNEL); ++ if (!request) ++ return -ENODEV; + +- acm->notify_req->complete = acm_cdc_notify_complete; +- acm->notify_req->context = acm; ++ request->complete = acm_cdc_notify_complete; ++ request->context = acm; + + /* support all relevant hardware speeds... we expect that when + * hardware is dual speed, all bulk-capable endpoints work at +@@ -692,7 +694,9 @@ acm_bind(struct usb_configuration *c, st + status = usb_assign_descriptors(f, acm_fs_function, acm_hs_function, + acm_ss_function, acm_ss_function); + if (status) +- goto fail; ++ return status; ++ ++ acm->notify_req = no_free_ptr(request); + + dev_dbg(&cdev->gadget->dev, + "acm ttyGS%d: IN/%s OUT/%s NOTIFY/%s\n", +@@ -700,14 +704,6 @@ acm_bind(struct usb_configuration *c, st + acm->port.in->name, acm->port.out->name, + acm->notify->name); + return 0; +- +-fail: +- if (acm->notify_req) +- gs_free_req(acm->notify, acm->notify_req); +- +- ERROR(cdev, "%s/%p: can't bind, err %d\n", f->name, f, status); +- +- return status; + } + + static void acm_unbind(struct usb_configuration *c, struct usb_function *f) diff --git a/queue-6.17/usb-gadget-f_ecm-refactor-bind-path-to-use-__free.patch b/queue-6.17/usb-gadget-f_ecm-refactor-bind-path-to-use-__free.patch new file mode 100644 index 0000000000..94eb6fc46f --- /dev/null +++ b/queue-6.17/usb-gadget-f_ecm-refactor-bind-path-to-use-__free.patch @@ -0,0 +1,158 @@ +From sashal@kernel.org Sat Oct 18 02:45:33 2025 +From: Sasha Levin +Date: Fri, 17 Oct 2025 20:45:26 -0400 +Subject: usb: gadget: f_ecm: Refactor bind path to use __free() +To: stable@vger.kernel.org +Cc: Kuen-Han Tsai , stable@kernel.org, Greg Kroah-Hartman , Sasha Levin +Message-ID: <20251018004526.94714-3-sashal@kernel.org> + +From: Kuen-Han Tsai + +[ Upstream commit 42988380ac67c76bb9dff8f77d7ef3eefd50b7b5 ] + +After an bind/unbind cycle, the ecm->notify_req is left stale. If a +subsequent bind fails, the unified error label attempts to free this +stale request, leading to a NULL pointer dereference when accessing +ep->ops->free_request. + +Refactor the error handling in the bind path to use the __free() +automatic cleanup mechanism. + +Fixes: da741b8c56d6 ("usb ethernet gadget: split CDC Ethernet function") +Cc: stable@kernel.org +Signed-off-by: Kuen-Han Tsai +Link: https://lore.kernel.org/r/20250916-ready-v1-5-4997bf277548@google.com +Signed-off-by: Greg Kroah-Hartman +Link: https://lore.kernel.org/r/20250916-ready-v1-5-4997bf277548@google.com +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/gadget/function/f_ecm.c | 48 +++++++++++++++--------------------- + 1 file changed, 20 insertions(+), 28 deletions(-) + +--- a/drivers/usb/gadget/function/f_ecm.c ++++ b/drivers/usb/gadget/function/f_ecm.c +@@ -8,6 +8,7 @@ + + /* #define VERBOSE_DEBUG */ + ++#include + #include + #include + #include +@@ -15,6 +16,8 @@ + #include + #include + ++#include ++ + #include "u_ether.h" + #include "u_ether_configfs.h" + #include "u_ecm.h" +@@ -678,6 +681,7 @@ ecm_bind(struct usb_configuration *c, st + struct usb_ep *ep; + + struct f_ecm_opts *ecm_opts; ++ struct usb_request *request __free(free_usb_request) = NULL; + + if (!can_support_ecm(cdev->gadget)) + return -EINVAL; +@@ -711,7 +715,7 @@ ecm_bind(struct usb_configuration *c, st + /* allocate instance-specific interface IDs */ + status = usb_interface_id(c, f); + if (status < 0) +- goto fail; ++ return status; + ecm->ctrl_id = status; + ecm_iad_descriptor.bFirstInterface = status; + +@@ -720,24 +724,22 @@ ecm_bind(struct usb_configuration *c, st + + status = usb_interface_id(c, f); + if (status < 0) +- goto fail; ++ return status; + ecm->data_id = status; + + ecm_data_nop_intf.bInterfaceNumber = status; + ecm_data_intf.bInterfaceNumber = status; + ecm_union_desc.bSlaveInterface0 = status; + +- status = -ENODEV; +- + /* allocate instance-specific endpoints */ + ep = usb_ep_autoconfig(cdev->gadget, &fs_ecm_in_desc); + if (!ep) +- goto fail; ++ return -ENODEV; + ecm->port.in_ep = ep; + + ep = usb_ep_autoconfig(cdev->gadget, &fs_ecm_out_desc); + if (!ep) +- goto fail; ++ return -ENODEV; + ecm->port.out_ep = ep; + + /* NOTE: a status/notification endpoint is *OPTIONAL* but we +@@ -746,20 +748,18 @@ ecm_bind(struct usb_configuration *c, st + */ + ep = usb_ep_autoconfig(cdev->gadget, &fs_ecm_notify_desc); + if (!ep) +- goto fail; ++ return -ENODEV; + ecm->notify = ep; + +- status = -ENOMEM; +- + /* allocate notification request and buffer */ +- ecm->notify_req = usb_ep_alloc_request(ep, GFP_KERNEL); +- if (!ecm->notify_req) +- goto fail; +- ecm->notify_req->buf = kmalloc(ECM_STATUS_BYTECOUNT, GFP_KERNEL); +- if (!ecm->notify_req->buf) +- goto fail; +- ecm->notify_req->context = ecm; +- ecm->notify_req->complete = ecm_notify_complete; ++ request = usb_ep_alloc_request(ep, GFP_KERNEL); ++ if (!request) ++ return -ENOMEM; ++ request->buf = kmalloc(ECM_STATUS_BYTECOUNT, GFP_KERNEL); ++ if (!request->buf) ++ return -ENOMEM; ++ request->context = ecm; ++ request->complete = ecm_notify_complete; + + /* support all relevant hardware speeds... we expect that when + * hardware is dual speed, all bulk-capable endpoints work at +@@ -778,7 +778,7 @@ ecm_bind(struct usb_configuration *c, st + status = usb_assign_descriptors(f, ecm_fs_function, ecm_hs_function, + ecm_ss_function, ecm_ss_function); + if (status) +- goto fail; ++ return status; + + /* NOTE: all that is done without knowing or caring about + * the network link ... which is unavailable to this code +@@ -788,20 +788,12 @@ ecm_bind(struct usb_configuration *c, st + ecm->port.open = ecm_open; + ecm->port.close = ecm_close; + ++ ecm->notify_req = no_free_ptr(request); ++ + DBG(cdev, "CDC Ethernet: IN/%s OUT/%s NOTIFY/%s\n", + ecm->port.in_ep->name, ecm->port.out_ep->name, + ecm->notify->name); + return 0; +- +-fail: +- if (ecm->notify_req) { +- kfree(ecm->notify_req->buf); +- usb_ep_free_request(ecm->notify, ecm->notify_req); +- } +- +- ERROR(cdev, "%s: can't bind, err %d\n", f->name, status); +- +- return status; + } + + static inline struct f_ecm_opts *to_f_ecm_opts(struct config_item *item) diff --git a/queue-6.17/usb-gadget-f_ncm-refactor-bind-path-to-use-__free.patch b/queue-6.17/usb-gadget-f_ncm-refactor-bind-path-to-use-__free.patch new file mode 100644 index 0000000000..fb3e8a4d71 --- /dev/null +++ b/queue-6.17/usb-gadget-f_ncm-refactor-bind-path-to-use-__free.patch @@ -0,0 +1,230 @@ +From stable+bounces-187728-greg=kroah.com@vger.kernel.org Sat Oct 18 01:43:25 2025 +From: Sasha Levin +Date: Fri, 17 Oct 2025 19:43:14 -0400 +Subject: usb: gadget: f_ncm: Refactor bind path to use __free() +To: stable@vger.kernel.org +Cc: Kuen-Han Tsai , stable@kernel.org, Greg Kroah-Hartman , Sasha Levin +Message-ID: <20251017234314.52983-3-sashal@kernel.org> + +From: Kuen-Han Tsai + +[ Upstream commit 75a5b8d4ddd4eb6b16cb0b475d14ff4ae64295ef ] + +After an bind/unbind cycle, the ncm->notify_req is left stale. If a +subsequent bind fails, the unified error label attempts to free this +stale request, leading to a NULL pointer dereference when accessing +ep->ops->free_request. + +Refactor the error handling in the bind path to use the __free() +automatic cleanup mechanism. + +Unable to handle kernel NULL pointer dereference at virtual address 0000000000000020 +Call trace: + usb_ep_free_request+0x2c/0xec + ncm_bind+0x39c/0x3dc + usb_add_function+0xcc/0x1f0 + configfs_composite_bind+0x468/0x588 + gadget_bind_driver+0x104/0x270 + really_probe+0x190/0x374 + __driver_probe_device+0xa0/0x12c + driver_probe_device+0x3c/0x218 + __device_attach_driver+0x14c/0x188 + bus_for_each_drv+0x10c/0x168 + __device_attach+0xfc/0x198 + device_initial_probe+0x14/0x24 + bus_probe_device+0x94/0x11c + device_add+0x268/0x48c + usb_add_gadget+0x198/0x28c + dwc3_gadget_init+0x700/0x858 + __dwc3_set_mode+0x3cc/0x664 + process_scheduled_works+0x1d8/0x488 + worker_thread+0x244/0x334 + kthread+0x114/0x1bc + ret_from_fork+0x10/0x20 + +Fixes: 9f6ce4240a2b ("usb: gadget: f_ncm.c added") +Cc: stable@kernel.org +Signed-off-by: Kuen-Han Tsai +Link: https://lore.kernel.org/r/20250916-ready-v1-3-4997bf277548@google.com +Signed-off-by: Greg Kroah-Hartman +Link: https://lore.kernel.org/r/20250916-ready-v1-3-4997bf277548@google.com +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/gadget/function/f_ncm.c | 78 +++++++++++++++--------------------- + 1 file changed, 33 insertions(+), 45 deletions(-) + +--- a/drivers/usb/gadget/function/f_ncm.c ++++ b/drivers/usb/gadget/function/f_ncm.c +@@ -11,6 +11,7 @@ + * Copyright (C) 2008 Nokia Corporation + */ + ++#include + #include + #include + #include +@@ -20,6 +21,7 @@ + #include + + #include ++#include + + #include "u_ether.h" + #include "u_ether_configfs.h" +@@ -1436,18 +1438,18 @@ static int ncm_bind(struct usb_configura + struct usb_ep *ep; + struct f_ncm_opts *ncm_opts; + ++ struct usb_os_desc_table *os_desc_table __free(kfree) = NULL; ++ struct usb_request *request __free(free_usb_request) = NULL; ++ + if (!can_support_ecm(cdev->gadget)) + return -EINVAL; + + ncm_opts = container_of(f->fi, struct f_ncm_opts, func_inst); + + if (cdev->use_os_string) { +- f->os_desc_table = kzalloc(sizeof(*f->os_desc_table), +- GFP_KERNEL); +- if (!f->os_desc_table) ++ os_desc_table = kzalloc(sizeof(*os_desc_table), GFP_KERNEL); ++ if (!os_desc_table) + return -ENOMEM; +- f->os_desc_n = 1; +- f->os_desc_table[0].os_desc = &ncm_opts->ncm_os_desc; + } + + mutex_lock(&ncm_opts->lock); +@@ -1459,16 +1461,15 @@ static int ncm_bind(struct usb_configura + mutex_unlock(&ncm_opts->lock); + + if (status) +- goto fail; ++ return status; + + ncm_opts->bound = true; + + us = usb_gstrings_attach(cdev, ncm_strings, + ARRAY_SIZE(ncm_string_defs)); +- if (IS_ERR(us)) { +- status = PTR_ERR(us); +- goto fail; +- } ++ if (IS_ERR(us)) ++ return PTR_ERR(us); ++ + ncm_control_intf.iInterface = us[STRING_CTRL_IDX].id; + ncm_data_nop_intf.iInterface = us[STRING_DATA_IDX].id; + ncm_data_intf.iInterface = us[STRING_DATA_IDX].id; +@@ -1478,20 +1479,16 @@ static int ncm_bind(struct usb_configura + /* allocate instance-specific interface IDs */ + status = usb_interface_id(c, f); + if (status < 0) +- goto fail; ++ return status; + ncm->ctrl_id = status; + ncm_iad_desc.bFirstInterface = status; + + ncm_control_intf.bInterfaceNumber = status; + ncm_union_desc.bMasterInterface0 = status; + +- if (cdev->use_os_string) +- f->os_desc_table[0].if_id = +- ncm_iad_desc.bFirstInterface; +- + status = usb_interface_id(c, f); + if (status < 0) +- goto fail; ++ return status; + ncm->data_id = status; + + ncm_data_nop_intf.bInterfaceNumber = status; +@@ -1500,35 +1497,31 @@ static int ncm_bind(struct usb_configura + + ecm_desc.wMaxSegmentSize = cpu_to_le16(ncm_opts->max_segment_size); + +- status = -ENODEV; +- + /* allocate instance-specific endpoints */ + ep = usb_ep_autoconfig(cdev->gadget, &fs_ncm_in_desc); + if (!ep) +- goto fail; ++ return -ENODEV; + ncm->port.in_ep = ep; + + ep = usb_ep_autoconfig(cdev->gadget, &fs_ncm_out_desc); + if (!ep) +- goto fail; ++ return -ENODEV; + ncm->port.out_ep = ep; + + ep = usb_ep_autoconfig(cdev->gadget, &fs_ncm_notify_desc); + if (!ep) +- goto fail; ++ return -ENODEV; + ncm->notify = ep; + +- status = -ENOMEM; +- + /* allocate notification request and buffer */ +- ncm->notify_req = usb_ep_alloc_request(ep, GFP_KERNEL); +- if (!ncm->notify_req) +- goto fail; +- ncm->notify_req->buf = kmalloc(NCM_STATUS_BYTECOUNT, GFP_KERNEL); +- if (!ncm->notify_req->buf) +- goto fail; +- ncm->notify_req->context = ncm; +- ncm->notify_req->complete = ncm_notify_complete; ++ request = usb_ep_alloc_request(ep, GFP_KERNEL); ++ if (!request) ++ return -ENOMEM; ++ request->buf = kmalloc(NCM_STATUS_BYTECOUNT, GFP_KERNEL); ++ if (!request->buf) ++ return -ENOMEM; ++ request->context = ncm; ++ request->complete = ncm_notify_complete; + + /* + * support all relevant hardware speeds... we expect that when +@@ -1548,7 +1541,7 @@ static int ncm_bind(struct usb_configura + status = usb_assign_descriptors(f, ncm_fs_function, ncm_hs_function, + ncm_ss_function, ncm_ss_function); + if (status) +- goto fail; ++ return status; + + /* + * NOTE: all that is done without knowing or caring about +@@ -1561,23 +1554,18 @@ static int ncm_bind(struct usb_configura + + hrtimer_setup(&ncm->task_timer, ncm_tx_timeout, CLOCK_MONOTONIC, HRTIMER_MODE_REL_SOFT); + ++ if (cdev->use_os_string) { ++ os_desc_table[0].os_desc = &ncm_opts->ncm_os_desc; ++ os_desc_table[0].if_id = ncm_iad_desc.bFirstInterface; ++ f->os_desc_table = no_free_ptr(os_desc_table); ++ f->os_desc_n = 1; ++ } ++ ncm->notify_req = no_free_ptr(request); ++ + DBG(cdev, "CDC Network: IN/%s OUT/%s NOTIFY/%s\n", + ncm->port.in_ep->name, ncm->port.out_ep->name, + ncm->notify->name); + return 0; +- +-fail: +- kfree(f->os_desc_table); +- f->os_desc_n = 0; +- +- if (ncm->notify_req) { +- kfree(ncm->notify_req->buf); +- usb_ep_free_request(ncm->notify, ncm->notify_req); +- } +- +- ERROR(cdev, "%s: can't bind, err %d\n", f->name, status); +- +- return status; + } + + static inline struct f_ncm_opts *to_f_ncm_opts(struct config_item *item)