From e41e6feb3d3b33f0793df6a1d9da20c8096a346e Mon Sep 17 00:00:00 2001 From: Andrew Goodbody Date: Mon, 29 Sep 2025 17:53:11 +0100 Subject: usb: ehci: exynos: variable node should be signed THe variable node is assigned to the return value of a function that returns an int. It is tested for being negative and then passed as an argument to a function that takes an int. So 'node' should not be declared as unsigned. Correct it. This issue was found by Smatch. Signed-off-by: Andrew Goodbody Reviewed-by: Marek Vasut --- drivers/usb/host/ehci-exynos.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/usb/host/ehci-exynos.c b/drivers/usb/host/ehci-exynos.c index 1e4a5a0b6f6..e1fc04efd2e 100644 --- a/drivers/usb/host/ehci-exynos.c +++ b/drivers/usb/host/ehci-exynos.c @@ -47,8 +47,7 @@ static int ehci_usb_of_to_plat(struct udevice *dev) { struct exynos_ehci_plat *plat = dev_get_plat(dev); const void *blob = gd->fdt_blob; - unsigned int node; - int depth; + int node, depth; /* * Get the base address for XHCI controller from the device node -- cgit v1.3.1 From 76d3b665310885f1a13ff83e818bb42f2cf26213 Mon Sep 17 00:00:00 2001 From: Andrew Goodbody Date: Thu, 25 Sep 2025 12:56:44 +0100 Subject: usb: fsl-dt-fixup: Return an error code on error fsl_fdt_fixup_usb_erratum uses strcmp to detect an error but then returns 'err' without it being set to an error. Calling code may not detect that an error occurred leading to a silent failure. Instead just return -EINVAL. This issue was found by Smatch. Signed-off-by: Andrew Goodbody --- drivers/usb/common/fsl-dt-fixup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/common/fsl-dt-fixup.c b/drivers/usb/common/fsl-dt-fixup.c index 6a68bd76c27..55176f7a871 100644 --- a/drivers/usb/common/fsl-dt-fixup.c +++ b/drivers/usb/common/fsl-dt-fixup.c @@ -99,7 +99,7 @@ static int fsl_fdt_fixup_usb_erratum(void *blob, const char *prop_erratum, else node_name = node_type; if (strcmp(node_name, controller_type)) - return err; + return -EINVAL; err = fdt_setprop(blob, node_offset, prop_erratum, NULL, 0); if (err < 0) { -- cgit v1.3.1 From 08f4c52c97ab3db174ce292eb86309ee29be5f07 Mon Sep 17 00:00:00 2001 From: Andrew Goodbody Date: Tue, 30 Sep 2025 10:56:02 +0100 Subject: usb: ohci-hcd: Null check lurb_priv before dereference When a variable needs a null check before it is dreferenced ensure that this is done even in the case of assignment on declaration. This was not happening for lurb_priv so correct it. This issue was found by Smatch. Signed-off-by: Andrew Goodbody --- drivers/usb/host/ohci-hcd.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c index 234a6f3645d..1d6711ccec4 100644 --- a/drivers/usb/host/ohci-hcd.c +++ b/drivers/usb/host/ohci-hcd.c @@ -1040,9 +1040,11 @@ static void dl_transfer_length(td_t *td) static void check_status(td_t *td_list) { urb_priv_t *lurb_priv = td_list->ed->purb; - int urb_len = lurb_priv->length; __u32 *phwHeadP = &td_list->ed->hwHeadP; - int cc; + int cc, urb_len; + + if (lurb_priv) + urb_len = lurb_priv->length; cc = TD_CC_GET(m32_swap(td_list->hwINFO)); if (cc) { -- cgit v1.3.1 From dd01b0541be38894c05f0dad2dad135ef1a9da6b Mon Sep 17 00:00:00 2001 From: Andrew Goodbody Date: Tue, 30 Sep 2025 17:06:44 +0100 Subject: usb: ulpi: Incorrect operator used Combining two bits into a mask to be used so that the same write code can be used to set or reset bits in a register clearly needs to use the binary 'or' operator, not the binary 'and'. Fix it. This issue was found by Smatch. Signed-off-by: Andrew Goodbody --- drivers/usb/ulpi/ulpi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/ulpi/ulpi.c b/drivers/usb/ulpi/ulpi.c index 128adcbde13..0e0f0e4983d 100644 --- a/drivers/usb/ulpi/ulpi.c +++ b/drivers/usb/ulpi/ulpi.c @@ -127,7 +127,7 @@ int ulpi_set_vbus_indicator(struct ulpi_viewport *ulpi_vp, int external, if (val == ULPI_ERROR) return val; - val = val & ~(ULPI_IFACE_PASSTHRU & ULPI_IFACE_EXTVBUS_COMPLEMENT); + val = val & ~(ULPI_IFACE_PASSTHRU | ULPI_IFACE_EXTVBUS_COMPLEMENT); val |= flags; val = ulpi_write(ulpi_vp, &ulpi->iface_ctrl, val); if (val) -- cgit v1.3.1 From adcec085e0dd3e399e6ee5ab5a7dd0e3cd192316 Mon Sep 17 00:00:00 2001 From: Andrew Goodbody Date: Tue, 30 Sep 2025 11:34:44 +0100 Subject: usb: xhci: exynos: variable node should be signed The variable node is assigned to the return value of a function that returns an int. It is tested for being negative and then passed as an argument to a function that takes an int. So 'node' should not be declared as unsigned. Correct it. This issue was found by Smatch. Signed-off-by: Andrew Goodbody --- drivers/usb/host/xhci-exynos5.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/usb/host/xhci-exynos5.c b/drivers/usb/host/xhci-exynos5.c index 6a2d422c4b8..c509ce1620a 100644 --- a/drivers/usb/host/xhci-exynos5.c +++ b/drivers/usb/host/xhci-exynos5.c @@ -56,8 +56,7 @@ static int xhci_usb_of_to_plat(struct udevice *dev) { struct exynos_xhci_plat *plat = dev_get_plat(dev); const void *blob = gd->fdt_blob; - unsigned int node; - int depth; + int node, depth; /* * Get the base address for XHCI controller from the device node -- cgit v1.3.1 From 6ea91bf8055b18b24828c449e33572ca9a9832eb Mon Sep 17 00:00:00 2001 From: Andrew Goodbody Date: Tue, 30 Sep 2025 16:52:22 +0100 Subject: usb: musb-new: Null check before dereference A null check for the variable 'data' was introduced before dereferencing it for set_phy_power but other uses were not so protected. Add the null check for other dereferences of 'data'. This issue was found by Smatch. Signed-off-by: Andrew Goodbody --- drivers/usb/musb-new/am35x.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/usb/musb-new/am35x.c b/drivers/usb/musb-new/am35x.c index 42bc816e4f1..ca4d798642e 100644 --- a/drivers/usb/musb-new/am35x.c +++ b/drivers/usb/musb-new/am35x.c @@ -402,7 +402,7 @@ static int am35x_musb_init(struct musb *musb) #endif /* Reset the musb */ - if (data->reset) + if (data && data->reset) data->reset(data->dev); /* Reset the controller */ @@ -417,7 +417,7 @@ static int am35x_musb_init(struct musb *musb) musb->isr = am35x_musb_interrupt; /* clear level interrupt */ - if (data->clear_irq) + if (data && data->clear_irq) data->clear_irq(data->dev); return 0; -- cgit v1.3.1 From d5de67c57e795325a67ec4ca6486654b72ade038 Mon Sep 17 00:00:00 2001 From: Andrew Goodbody Date: Tue, 30 Sep 2025 16:52:23 +0100 Subject: usb: musb-new: Limit check array index before use epnum is used as an index into an array. The limit check for this index should be performed before using it to access an element in the array to prevent possible bounds overrun. This issue was found by Smatch. Signed-off-by: Andrew Goodbody Reviewed-by: Mattijs Korpershoek --- drivers/usb/musb-new/musb_gadget_ep0.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/usb/musb-new/musb_gadget_ep0.c b/drivers/usb/musb-new/musb_gadget_ep0.c index ea65326ab62..25b1de6e58f 100644 --- a/drivers/usb/musb-new/musb_gadget_ep0.c +++ b/drivers/usb/musb-new/musb_gadget_ep0.c @@ -96,6 +96,9 @@ static int service_tx_status_request( if (!epnum) { result[0] = 0; break; + } else if (epnum >= MUSB_C_NUM_EPS) { + handled = -EINVAL; + break; } is_in = epnum & USB_DIR_IN; @@ -107,7 +110,7 @@ static int service_tx_status_request( } regs = musb->endpoints[epnum].regs; - if (epnum >= MUSB_C_NUM_EPS || !ep->desc) { + if (!ep->desc) { handled = -EINVAL; break; } -- cgit v1.3.1 From 41fd18219fb6625171180a21d0e4f17e9b7b5aa2 Mon Sep 17 00:00:00 2001 From: Andrew Goodbody Date: Tue, 30 Sep 2025 16:52:24 +0100 Subject: usb: musb-new: Cannot test unsigned member to be negative You cannot test an unsigned member of a struct for being negative, the test will always fail. Instead assign the return value of fdtdec_get_int, which returns an int, to a temporary variable declared as an int, so that it can be tested for being negative before being assigned to the unsigned struct member. This issue was found by Smatch. Signed-off-by: Andrew Goodbody --- drivers/usb/musb-new/omap2430.c | 34 +++++++++++++++++++++------------- drivers/usb/musb-new/ti-musb.c | 28 +++++++++++++++++----------- 2 files changed, 38 insertions(+), 24 deletions(-) diff --git a/drivers/usb/musb-new/omap2430.c b/drivers/usb/musb-new/omap2430.c index ba600d01102..7fd6639013a 100644 --- a/drivers/usb/musb-new/omap2430.c +++ b/drivers/usb/musb-new/omap2430.c @@ -142,41 +142,49 @@ static int omap2430_musb_of_to_plat(struct udevice *dev) struct omap2430_musb_plat *plat = dev_get_plat(dev); const void *fdt = gd->fdt_blob; int node = dev_of_offset(dev); + int ret; plat->base = (void *)dev_read_addr_ptr(dev); - plat->musb_config.multipoint = fdtdec_get_int(fdt, node, "multipoint", - -1); - if (plat->musb_config.multipoint < 0) { + ret = fdtdec_get_int(fdt, node, "multipoint", -1); + if (ret < 0) { pr_err("MUSB multipoint DT entry missing\n"); return -ENOENT; + } else { + plat->musb_config.multipoint = ret; } plat->musb_config.dyn_fifo = 1; - plat->musb_config.num_eps = fdtdec_get_int(fdt, node, "num-eps", -1); - if (plat->musb_config.num_eps < 0) { + ret = fdtdec_get_int(fdt, node, "num-eps", -1); + if (ret < 0) { pr_err("MUSB num-eps DT entry missing\n"); return -ENOENT; + } else { + plat->musb_config.num_eps = ret; } - plat->musb_config.ram_bits = fdtdec_get_int(fdt, node, "ram-bits", -1); - if (plat->musb_config.ram_bits < 0) { + ret = fdtdec_get_int(fdt, node, "ram-bits", -1); + if (ret < 0) { pr_err("MUSB ram-bits DT entry missing\n"); return -ENOENT; + } else { + plat->musb_config.ram_bits = ret; } - plat->plat.power = fdtdec_get_int(fdt, node, "power", -1); - if (plat->plat.power < 0) { + ret = fdtdec_get_int(fdt, node, "power", -1); + if (ret < 0) { pr_err("MUSB power DT entry missing\n"); return -ENOENT; + } else { + plat->plat.power = ret; } - plat->otg_board_data.interface_type = fdtdec_get_int(fdt, node, - "interface-type", - -1); - if (plat->otg_board_data.interface_type < 0) { + ret = fdtdec_get_int(fdt, node, "interface-type", -1); + if (ret < 0) { pr_err("MUSB interface-type DT entry missing\n"); return -ENOENT; + } else { + plat->otg_board_data.interface_type = ret; } #if 0 /* In a perfect world, mode would be set to OTG, mode 3 from DT */ diff --git a/drivers/usb/musb-new/ti-musb.c b/drivers/usb/musb-new/ti-musb.c index 967d0953875..bcd31adba52 100644 --- a/drivers/usb/musb-new/ti-musb.c +++ b/drivers/usb/musb-new/ti-musb.c @@ -86,6 +86,7 @@ static int ti_musb_of_to_plat(struct udevice *dev) int phys; int ctrl_mod; int usb_index; + int ret; struct musb_hdrc_config *musb_config; plat->base = devfdt_get_addr_index_ptr(dev, 1); @@ -108,35 +109,40 @@ static int ti_musb_of_to_plat(struct udevice *dev) musb_config = malloc(sizeof(struct musb_hdrc_config)); memset(musb_config, 0, sizeof(struct musb_hdrc_config)); - musb_config->multipoint = fdtdec_get_int(fdt, node, - "mentor,multipoint", -1); - if (musb_config->multipoint < 0) { + ret = fdtdec_get_int(fdt, node, "mentor,multipoint", -1); + if (ret < 0) { pr_err("MUSB multipoint DT entry missing\n"); return -ENOENT; + } else { + musb_config->multipoint = ret; } musb_config->dyn_fifo = 1; - musb_config->num_eps = fdtdec_get_int(fdt, node, "mentor,num-eps", - -1); - if (musb_config->num_eps < 0) { + ret = fdtdec_get_int(fdt, node, "mentor,num-eps", -1); + if (ret < 0) { pr_err("MUSB num-eps DT entry missing\n"); return -ENOENT; + } else { + musb_config->num_eps = ret; } - musb_config->ram_bits = fdtdec_get_int(fdt, node, "mentor,ram-bits", - -1); - if (musb_config->ram_bits < 0) { + ret = fdtdec_get_int(fdt, node, "mentor,ram-bits", -1); + if (ret < 0) { pr_err("MUSB ram-bits DT entry missing\n"); return -ENOENT; + } else { + musb_config->ram_bits = ret; } plat->plat.config = musb_config; - plat->plat.power = fdtdec_get_int(fdt, node, "mentor,power", -1); - if (plat->plat.power < 0) { + ret = fdtdec_get_int(fdt, node, "mentor,power", -1); + if (ret < 0) { pr_err("MUSB mentor,power DT entry missing\n"); return -ENOENT; + } else { + plat->plat.power = ret; } plat->plat.platform_ops = &musb_dsps_ops; -- cgit v1.3.1