FAILED: patch "[PATCH] usb: gadget: f_ecm: Refactor bind path to use __free()" failed to apply to 5.4-stable tree
Subsystems (2)
[email protected]
maintainerThe patch below does not apply to the 5.4-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
To reproduce the conflict and resubmit, you may use the following commands:
git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-5.4.y
git checkout FETCH_HEAD
git cherry-pick -x 42988380ac67c76bb9dff8f77d7ef3eefd50b7b5
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<[email protected]>' --in-reply-to '2025101601-suitor-ultimate-15f4@gregkh' --subject-prefix 'PATCH 5.4.y' HEAD^..
Possible dependencies:
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From 42988380ac67c76bb9dff8f77d7ef3eefd50b7b5 Mon Sep 17 00:00:00 2001
From: Kuen-Han Tsai <[email protected]>
Date: Tue, 16 Sep 2025 16:21:36 +0800
Subject: [PATCH] usb: gadget: f_ecm: Refactor bind path to use __free()
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.
drivers/usb/gadget/function/f_ecm.c +20 -28
@@ -8,6 +8,7 @@/* #define VERBOSE_DEBUG */ +#include <linux/cleanup.h> #include <linux/slab.h> #include <linux/kernel.h> #include <linux/module.h>
@@ -15,6 +16,8 @@#include <linux/etherdevice.h> #include <linux/string_choices.h> +#include <linux/usb/gadget.h> +#include "u_ether.h" #include "u_ether_configfs.h" #include "u_ecm.h"
@@ -678,6 +681,7 @@ ecm_bind(struct usb_configuration *c, struct usb_function *f)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, struct usb_function *f)/* 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, struct usb_function *f) 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, struct usb_function *f)*/ 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, struct usb_function *f) 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, struct usb_function *f) 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)