From 7cedd20ed384a9748bba3fee05d504674109087a Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Mon, 24 Mar 2025 15:39:43 +0100 Subject: [PATCH 1/8] usb: dwc3: gadget: Fix excepts/expects typo Fix the excepts typo to expects , no functional change. Fixes: 0916053ebc56 ("usb: dwc3: gadget: Fix match_ep callback for NXP UUU tool") Signed-off-by: Marek Vasut Reviewed-by: Neil Armstrong Reviewed-by: Mattijs Korpershoek Link: https://lore.kernel.org/r/20250324143956.91791-1-marex@denx.de Signed-off-by: Mattijs Korpershoek --- drivers/usb/dwc3/gadget.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 477ecd02098..2b01113d54c 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -1635,7 +1635,7 @@ usb_ep *dwc3_gadget_match_ep(struct usb_gadget *gadget, /* * Special workaround for NXP UUU tool in SPL. * - * The tool excepts the interrupt-in endpoint to be ep1in, + * The tool expects the interrupt-in endpoint to be ep1in, * otherwise it crashes. This is a result of the previous * hard-coded EP setup in drivers/usb/gadget/epautoconf.c * which did special-case EP allocation for SPL builds, From d3c9f810f2b317ba376b4d9556e63a043b210355 Mon Sep 17 00:00:00 2001 From: Michael Walle Date: Wed, 12 Mar 2025 08:36:55 +0100 Subject: [PATCH 2/8] fastboot: lift restrictions on !NET_LWIP for USB Fastboot works either over TCP, UDP or USB. The latter doesn't have anything to do with networking, thus should work just fine with regardless which network stack is selected. In practice, header symbols are used inside common code paths. Add some ifdeffery to guard against that. This will make fastboot over USB work with the new LWIP stack. Signed-off-by: Michael Walle Reviewed-by: Jerome Forissier Reviewed-by: Mattijs Korpershoek Link: https://lore.kernel.org/r/20250312073655.2281377-1-mwalle@kernel.org Signed-off-by: Mattijs Korpershoek --- cmd/fastboot.c | 4 ++++ drivers/fastboot/Kconfig | 1 - drivers/fastboot/fb_common.c | 4 ++++ 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/cmd/fastboot.c b/cmd/fastboot.c index d4cfc0c7a28..be84a482b81 100644 --- a/cmd/fastboot.c +++ b/cmd/fastboot.c @@ -16,6 +16,7 @@ #include #include +#if CONFIG_IS_ENABLED(NET) static int do_fastboot_udp(int argc, char *const argv[], uintptr_t buf_addr, size_t buf_size) { @@ -55,6 +56,7 @@ static int do_fastboot_tcp(int argc, char *const argv[], return CMD_RET_SUCCESS; } +#endif static int do_fastboot_usb(int argc, char *const argv[], uintptr_t buf_addr, size_t buf_size) @@ -160,10 +162,12 @@ NXTARG: fastboot_init((void *)buf_addr, buf_size); +#if CONFIG_IS_ENABLED(NET) if (!strcmp(argv[1], "udp")) return do_fastboot_udp(argc, argv, buf_addr, buf_size); if (!strcmp(argv[1], "tcp")) return do_fastboot_tcp(argc, argv, buf_addr, buf_size); +#endif if (!strcmp(argv[1], "usb")) { argv++; argc--; diff --git a/drivers/fastboot/Kconfig b/drivers/fastboot/Kconfig index 1eb460f5a02..70207573de2 100644 --- a/drivers/fastboot/Kconfig +++ b/drivers/fastboot/Kconfig @@ -1,6 +1,5 @@ menu "Fastboot support" depends on CMDLINE - depends on !NET_LWIP config FASTBOOT bool diff --git a/drivers/fastboot/fb_common.c b/drivers/fastboot/fb_common.c index 12ffb463deb..68f92c4b887 100644 --- a/drivers/fastboot/fb_common.c +++ b/drivers/fastboot/fb_common.c @@ -183,11 +183,15 @@ void fastboot_handle_boot(int command, bool success) switch (command) { case FASTBOOT_COMMAND_BOOT: fastboot_boot(); +#if CONFIG_IS_ENABLED(NET) net_set_state(NETLOOP_SUCCESS); +#endif break; case FASTBOOT_COMMAND_CONTINUE: +#if CONFIG_IS_ENABLED(NET) net_set_state(NETLOOP_SUCCESS); +#endif break; case FASTBOOT_COMMAND_REBOOT: From a4317be9dbe9428f6209cb5595bfc57eb990b023 Mon Sep 17 00:00:00 2001 From: Mattijs Korpershoek Date: Fri, 28 Mar 2025 09:15:41 +0100 Subject: [PATCH 3/8] usb: gadget: f_mass_storage: Remove kref structure use The kref structure is locally to f_mass_storage and is not used anywhere beside in fsg_common_release(). Remove it and use struct fsg_common* instead. No functional change. Signed-off-by: Mattijs Korpershoek Tested-by: Zixun LI # on SAM9X60 Link: https://lore.kernel.org/r/20250328-ums-gadget-leak-v1-1-3b677db99bde@baylibre.com Signed-off-by: Mattijs Korpershoek --- drivers/usb/gadget/f_mass_storage.c | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c index d3fc4acb401..bd749c033f9 100644 --- a/drivers/usb/gadget/f_mass_storage.c +++ b/drivers/usb/gadget/f_mass_storage.c @@ -284,7 +284,6 @@ static const char fsg_string_interface[] = "Mass Storage"; #define kthread_create(...) __builtin_return_address(0) #define wait_for_completion(...) do {} while (0) -struct kref {int x; }; struct completion {int x; }; struct fsg_dev; @@ -345,8 +344,6 @@ struct fsg_common { /* Vendor (8 chars), product (16 chars), release (4 * hexadecimal digits) and NUL byte */ char inquiry_string[8 + 16 + 4 + 1]; - - struct kref ref; }; struct fsg_config { @@ -2436,7 +2433,7 @@ int fsg_main_thread(void *common_) return 0; } -static void fsg_common_release(struct kref *ref); +static void fsg_common_release(struct fsg_common *common); static struct fsg_common *fsg_common_init(struct fsg_common *common, struct usb_composite_dev *cdev) @@ -2548,16 +2545,12 @@ error_luns: common->nluns = i + 1; error_release: common->state = FSG_STATE_TERMINATED; /* The thread is dead */ - /* Call fsg_common_release() directly, ref might be not - * initialised */ - fsg_common_release(&common->ref); + fsg_common_release(common); return ERR_PTR(rc); } -static void fsg_common_release(struct kref *ref) +static void fsg_common_release(struct fsg_common *common) { - struct fsg_common *common = container_of(ref, struct fsg_common, ref); - /* If the thread isn't already dead, tell it to exit now */ if (common->state != FSG_STATE_TERMINATED) { raise_exception(common, FSG_STATE_EXIT); From 47fd46db943a55a7e0232e27224d216b774d7575 Mon Sep 17 00:00:00 2001 From: Mattijs Korpershoek Date: Fri, 28 Mar 2025 09:15:42 +0100 Subject: [PATCH 4/8] usb: gadget: f_mass_storage: Drop invalid kfree() in fsg_common_release() Boards with low memory (CONFIG_SYS_MALLOC_LEN=0x81000), can be crashed using the => ums command twice in row: => ums 0 mmc 2 UMS: LUN 0, dev mmc 2, hwpart 0, sector 0x0, count 0x3a3e000 |crq->brequest:0x0 CTRL+C - Operation aborted => ums 0 mmc 2 UMS: LUN 0, dev mmc 2, hwpart 0, sector 0x0, count 0x3a3e000 "Synchronous Abort" handler, esr 0x96000004, far 0xfffffffff2ea20f0 elr: 000000000102ea78 lr : 000000000105e028 (reloc) elr: 00000000f2f33a78 lr : 00000000f2f63028 x0 : 0000000100000000 x1 : 0000000100000000 x2 : 0000000000000000 x3 : fffffffff2ea20e0 x4 : 00000000f2fc9720 x5 : 00000000f2ea20e0 x6 : 00000000f2fc9730 x7 : 00000000f2ee4780 x8 : 000000000000003f x9 : 0000000000000004 x10: 0000000000000058 x11: 00000000000058c4 x12: 0000000000000000 x13: 00000000f2e60800 x14: 00000000f4ec0040 x15: 0000000000000000 x16: 00000000f2f62f2c x17: 0000000000c0c0c0 x18: 00000000f2e73e00 x19: 00000000f2ea2010 x20: 00000000fffffff4 x21: 00000000f2e9b500 x22: 00000000f2ea20f0 x23: 00000000f2ea2050 x24: 00000000f2f61eec x25: 00000000f2fcf000 x26: 00000000f2e9fcd0 x27: 0000000000000000 x28: 0000000000000000 x29: 00000000f2e60290 Code: d00004a6 911cc0c6 cb000063 8b000021 (f9400860) Resetting CPU ... This happens when fsg_common_init() fails to allocate memory and calls fsg_common_release(). fsg_common_release() then calls kfree() which frees common->luns. However, common->luns was never allocated via kmalloc/calloc(), resulting in a crash. Drop the invalid kfree. The memory from common->luns will be reclaimed when we kfree(common) later in fgs_common_release(). Reported-by: Zixun LI Signed-off-by: Mattijs Korpershoek Tested-by: Zixun LI # on SAM9X60 Link: https://lore.kernel.org/r/20250328-ums-gadget-leak-v1-2-3b677db99bde@baylibre.com Signed-off-by: Mattijs Korpershoek --- drivers/usb/gadget/f_mass_storage.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c index bd749c033f9..6f464185bd3 100644 --- a/drivers/usb/gadget/f_mass_storage.c +++ b/drivers/usb/gadget/f_mass_storage.c @@ -2564,8 +2564,6 @@ static void fsg_common_release(struct fsg_common *common) /* In error recovery common->nluns may be zero. */ for (; i; --i, ++lun) fsg_lun_close(lun); - - kfree(common->luns); } { From 6c9eaec55ae634bac02e0cf70eb78c879d008a5c Mon Sep 17 00:00:00 2001 From: Mattijs Korpershoek Date: Fri, 28 Mar 2025 09:15:43 +0100 Subject: [PATCH 5/8] usb: gadget: f_mass_storage: Fix NULL dereference in fsg_add() fsg_common_init() can fail when memory is low. In that case, it returns PTR_ERR(). fsg_add() does not check for failure, and thus dereferences an invalid fsg_common later, which crashes. Verify if we receive an error from fsg_common_init() and handle it gracefully. Reported-by: Zixun LI Signed-off-by: Mattijs Korpershoek Tested-by: Zixun LI # on SAM9X60 Link: https://lore.kernel.org/r/20250328-ums-gadget-leak-v1-3-3b677db99bde@baylibre.com Signed-off-by: Mattijs Korpershoek --- drivers/usb/gadget/f_mass_storage.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c index 6f464185bd3..fcce6d12f56 100644 --- a/drivers/usb/gadget/f_mass_storage.c +++ b/drivers/usb/gadget/f_mass_storage.c @@ -2742,6 +2742,8 @@ int fsg_add(struct usb_configuration *c) struct fsg_common *fsg_common; fsg_common = fsg_common_init(NULL, c->cdev); + if (IS_ERR(fsg_common)) + return PTR_ERR(fsg_common); fsg_common->vendor_name = 0; fsg_common->product_name = 0; From c76a7090f6480affbe3946fcd0dcc6df9bfe05b3 Mon Sep 17 00:00:00 2001 From: Mattijs Korpershoek Date: Fri, 28 Mar 2025 09:15:44 +0100 Subject: [PATCH 6/8] usb: gadget: f_mass_storage: Fix memory leak of fsg buffers In fsg_common_init, we allocate some buffers via memalign(). However, these buffers are never freed. Because of that, we cannot call => ums command multiple times on boards with low memory (CONFIG_SYS_MALLOC_LEN=0x81000): => ums 0 mmc 2 UMS: LUN 0, dev mmc 2, hwpart 0, sector 0x0, count 0x3a3e000 |crq->brequest:0x0 CTRL+C - Operation aborted => ums 0 mmc 2 UMS: LUN 0, dev mmc 2, hwpart 0, sector 0x0, count 0x3a3e000 failed to start : -12 g_dnl_register: failed!, error: -12 g_dnl_register failed Make sure the fsg buffers are freed when the gadget is unbound by calling fsg_common_release() in fsg_unbind(). Reported-by: Zixun LI Signed-off-by: Mattijs Korpershoek Tested-by: Zixun LI # on SAM9X60 Link: https://lore.kernel.org/r/20250328-ums-gadget-leak-v1-4-3b677db99bde@baylibre.com Signed-off-by: Mattijs Korpershoek --- drivers/usb/gadget/f_mass_storage.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c index fcce6d12f56..71dc58da3f0 100644 --- a/drivers/usb/gadget/f_mass_storage.c +++ b/drivers/usb/gadget/f_mass_storage.c @@ -2639,6 +2639,7 @@ static void fsg_unbind(struct usb_configuration *c, struct usb_function *f) raise_exception(fsg->common, FSG_STATE_CONFIG_CHANGE); } + fsg_common_release(fsg->common); free(fsg->function.descriptors); free(fsg->function.hs_descriptors); kfree(fsg); From dc22cf37af6d604513f8c6f02d4cb551d5a59435 Mon Sep 17 00:00:00 2001 From: Zixun LI Date: Mon, 31 Mar 2025 18:26:07 +0200 Subject: [PATCH 7/8] usb: gadget: atmel: Add SAM9X60 support Compared to SAM9X5 the only difference is the DPRAM memory from the USB High Speed Device Port (UDPHS) hardware block was increased, so we can reuse the same endpoint data. Also add compatible "microchip,sam9x60-udc". Signed-off-by: Zixun LI Reviewed-by: Mattijs Korpershoek Link: https://lore.kernel.org/r/20250331162611.1557759-2-admin@hifiphile.com Signed-off-by: Mattijs Korpershoek --- arch/arm/mach-at91/include/mach/atmel_usba_udc.h | 2 +- drivers/usb/gadget/atmel_usba_udc.c | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/arm/mach-at91/include/mach/atmel_usba_udc.h b/arch/arm/mach-at91/include/mach/atmel_usba_udc.h index 835b47d91ba..23c71985c90 100644 --- a/arch/arm/mach-at91/include/mach/atmel_usba_udc.h +++ b/arch/arm/mach-at91/include/mach/atmel_usba_udc.h @@ -20,7 +20,7 @@ } #if defined(CONFIG_AT91SAM9G45) || defined(CONFIG_AT91SAM9M10G45) || \ - defined(CONFIG_AT91SAM9X5) + defined(CONFIG_AT91SAM9X5) || defined(CONFIG_SAM9X60) static struct usba_ep_data usba_udc_ep[] = { EP("ep0", 0, 64, 1, 0, 0), EP("ep1", 1, 1024, 2, 1, 1), diff --git a/drivers/usb/gadget/atmel_usba_udc.c b/drivers/usb/gadget/atmel_usba_udc.c index a77037a7094..f9326f0a7e7 100644 --- a/drivers/usb/gadget/atmel_usba_udc.c +++ b/drivers/usb/gadget/atmel_usba_udc.c @@ -1443,6 +1443,7 @@ static const struct udevice_id usba_udc_ids[] = { { .compatible = "atmel,at91sam9rl-udc" }, { .compatible = "atmel,at91sam9g45-udc" }, { .compatible = "atmel,sama5d3-udc" }, + { .compatible = "microchip,sam9x60-udc" }, {} }; From df50c821e75957113b93e45b363cb22c965e7a9b Mon Sep 17 00:00:00 2001 From: Gary Bisson Date: Wed, 2 Apr 2025 16:42:19 +0200 Subject: [PATCH 8/8] bootstd: android: avoid possible null pointer dereference - avb_slot_verify_data_free() doesn't check its data parameter - out_data can be null if avb_slot_verify() fails to allocate memory Signed-off-by: Gary Bisson Reviewed-by: Mattijs Korpershoek Link: https://lore.kernel.org/r/20250402144219.1875067-1-bisson.gary@gmail.com Signed-off-by: Mattijs Korpershoek --- boot/bootmeth_android.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/boot/bootmeth_android.c b/boot/bootmeth_android.c index a5a86b29d7f..654ebfdf1fc 100644 --- a/boot/bootmeth_android.c +++ b/boot/bootmeth_android.c @@ -455,7 +455,8 @@ static int run_avb_verification(struct bootflow *bflow) if (result != AVB_SLOT_VERIFY_RESULT_OK) { printf("Verification failed, reason: %s\n", str_avb_slot_error(result)); - avb_slot_verify_data_free(out_data); + if (out_data) + avb_slot_verify_data_free(out_data); return log_msg_ret("avb verify", -EIO); } boot_state = AVB_GREEN; @@ -465,7 +466,8 @@ static int run_avb_verification(struct bootflow *bflow) result != AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION) { printf("Unlocked verification failed, reason: %s\n", str_avb_slot_error(result)); - avb_slot_verify_data_free(out_data); + if (out_data) + avb_slot_verify_data_free(out_data); return log_msg_ret("avb verify unlocked", -EIO); } boot_state = AVB_ORANGE;