Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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.

Fixes: da741b8c56d6 ("usb ethernet gadget: split CDC Ethernet function")
Cc: stable@kernel.org
Signed-off-by: Kuen-Han Tsai <khtsai@google.com>
Link: https://lore.kernel.org/r/20250916-ready-v1-5-4997bf277548@google.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Link: https://lore.kernel.org/r/20250916-ready-v1-5-4997bf277548@google.com

authored by

Kuen-Han Tsai and committed by
Greg Kroah-Hartman
42988380 47b2116e

+20 -28
+20 -28
drivers/usb/gadget/function/f_ecm.c
··· 8 8 9 9 /* #define VERBOSE_DEBUG */ 10 10 11 + #include <linux/cleanup.h> 11 12 #include <linux/slab.h> 12 13 #include <linux/kernel.h> 13 14 #include <linux/module.h> 14 15 #include <linux/device.h> 15 16 #include <linux/etherdevice.h> 16 17 #include <linux/string_choices.h> 18 + 19 + #include <linux/usb/gadget.h> 17 20 18 21 #include "u_ether.h" 19 22 #include "u_ether_configfs.h" ··· 681 678 struct usb_ep *ep; 682 679 683 680 struct f_ecm_opts *ecm_opts; 681 + struct usb_request *request __free(free_usb_request) = NULL; 684 682 685 683 if (!can_support_ecm(cdev->gadget)) 686 684 return -EINVAL; ··· 715 711 /* allocate instance-specific interface IDs */ 716 712 status = usb_interface_id(c, f); 717 713 if (status < 0) 718 - goto fail; 714 + return status; 719 715 ecm->ctrl_id = status; 720 716 ecm_iad_descriptor.bFirstInterface = status; 721 717 ··· 724 720 725 721 status = usb_interface_id(c, f); 726 722 if (status < 0) 727 - goto fail; 723 + return status; 728 724 ecm->data_id = status; 729 725 730 726 ecm_data_nop_intf.bInterfaceNumber = status; 731 727 ecm_data_intf.bInterfaceNumber = status; 732 728 ecm_union_desc.bSlaveInterface0 = status; 733 729 734 - status = -ENODEV; 735 - 736 730 /* allocate instance-specific endpoints */ 737 731 ep = usb_ep_autoconfig(cdev->gadget, &fs_ecm_in_desc); 738 732 if (!ep) 739 - goto fail; 733 + return -ENODEV; 740 734 ecm->port.in_ep = ep; 741 735 742 736 ep = usb_ep_autoconfig(cdev->gadget, &fs_ecm_out_desc); 743 737 if (!ep) 744 - goto fail; 738 + return -ENODEV; 745 739 ecm->port.out_ep = ep; 746 740 747 741 /* NOTE: a status/notification endpoint is *OPTIONAL* but we ··· 748 746 */ 749 747 ep = usb_ep_autoconfig(cdev->gadget, &fs_ecm_notify_desc); 750 748 if (!ep) 751 - goto fail; 749 + return -ENODEV; 752 750 ecm->notify = ep; 753 751 754 - status = -ENOMEM; 755 - 756 752 /* allocate notification request and buffer */ 757 - ecm->notify_req = usb_ep_alloc_request(ep, GFP_KERNEL); 758 - if (!ecm->notify_req) 759 - goto fail; 760 - ecm->notify_req->buf = kmalloc(ECM_STATUS_BYTECOUNT, GFP_KERNEL); 761 - if (!ecm->notify_req->buf) 762 - goto fail; 763 - ecm->notify_req->context = ecm; 764 - ecm->notify_req->complete = ecm_notify_complete; 753 + request = usb_ep_alloc_request(ep, GFP_KERNEL); 754 + if (!request) 755 + return -ENOMEM; 756 + request->buf = kmalloc(ECM_STATUS_BYTECOUNT, GFP_KERNEL); 757 + if (!request->buf) 758 + return -ENOMEM; 759 + request->context = ecm; 760 + request->complete = ecm_notify_complete; 765 761 766 762 /* support all relevant hardware speeds... we expect that when 767 763 * hardware is dual speed, all bulk-capable endpoints work at ··· 778 778 status = usb_assign_descriptors(f, ecm_fs_function, ecm_hs_function, 779 779 ecm_ss_function, ecm_ss_function); 780 780 if (status) 781 - goto fail; 781 + return status; 782 782 783 783 /* NOTE: all that is done without knowing or caring about 784 784 * the network link ... which is unavailable to this code ··· 788 788 ecm->port.open = ecm_open; 789 789 ecm->port.close = ecm_close; 790 790 791 + ecm->notify_req = no_free_ptr(request); 792 + 791 793 DBG(cdev, "CDC Ethernet: IN/%s OUT/%s NOTIFY/%s\n", 792 794 ecm->port.in_ep->name, ecm->port.out_ep->name, 793 795 ecm->notify->name); 794 796 return 0; 795 - 796 - fail: 797 - if (ecm->notify_req) { 798 - kfree(ecm->notify_req->buf); 799 - usb_ep_free_request(ecm->notify, ecm->notify_req); 800 - } 801 - 802 - ERROR(cdev, "%s: can't bind, err %d\n", f->name, status); 803 - 804 - return status; 805 797 } 806 798 807 799 static inline struct f_ecm_opts *to_f_ecm_opts(struct config_item *item)