From s.hauer at pengutronix.de Mon Jun 1 05:29:52 2026 From: s.hauer at pengutronix.de (Sascha Hauer) Date: Mon, 01 Jun 2026 14:29:52 +0200 Subject: [PATCH 0/3] debug_ll: Cleanup conflicts for multiple SoCs Message-ID: <20260601-debug-ll-conflicts-v1-0-bf17f9f0e23a@pengutronix.de> This cleans up some problems we have with debug_ll when it comes to multi SoC images. debug_ll relies on having exactly one PUTC_LL() implementation available. Most SoCs have their own DEBUG_*_UART Kconfig option and the Kconfig choice around them makes sure only a single debug UART can be selected. Some SoCs do not have a dedicated option though and provide PUTC_LL() whenever the SoC is enabled which can to multiple definitions of PUTC_LL(). Fix that by adding a DEBUG_*_UART option to the SoC that currently do not have one. Another problem is that pl011.h provides PUTC_LL() and debug_ll_pl011_putc(). The former is needed when included indirectly from debug_ll.h, the latter is needed by board code to specify a putc() to the PBL console. This too ends up in multiple definitions of PUTC_LL(). Both problems are fixed in this series Signed-off-by: Sascha Hauer --- Sascha Hauer (3): debug_ll: give PUTC_LL a common prototype debug_ll: Add Kconfig options for debug uarts that have none debug_ll: pl011: define PUTC_LL only when requested arch/arm/include/asm/debug_ll.h | 69 ++++++++-------------- .../mips/mach-ath79/include/mach/debug_ll_ar9331.h | 2 +- arch/openrisc/include/asm/debug_ll.h | 2 +- arch/powerpc/include/asm/debug_ll.h | 2 +- common/Kconfig.debug_ll | 28 +++++++++ include/debug_ll.h | 2 + include/debug_ll/pl011.h | 6 +- include/mach/bcm283x/debug_ll.h | 4 +- include/mach/imx/debug_ll.h | 2 +- include/mach/k3/debug_ll.h | 2 +- include/mach/layerscape/debug_ll.h | 2 +- include/mach/mxs/debug_ll.h | 2 +- include/mach/omap/debug_ll.h | 2 +- include/mach/rockchip/debug_ll.h | 2 +- include/mach/stm32mp/debug_ll.h | 2 +- include/mach/zynq/debug_ll.h | 2 +- include/mach/zynqmp/debug_ll.h | 2 +- 17 files changed, 69 insertions(+), 64 deletions(-) --- base-commit: 81fbe2e8d0d445032498a0bfecf9fd270f00985a change-id: 20260601-debug-ll-conflicts-a5aeab40b99b Best regards, -- Sascha Hauer From s.hauer at pengutronix.de Mon Jun 1 05:29:55 2026 From: s.hauer at pengutronix.de (Sascha Hauer) Date: Mon, 01 Jun 2026 14:29:55 +0200 Subject: [PATCH 3/3] debug_ll: pl011: define PUTC_LL only when requested In-Reply-To: <20260601-debug-ll-conflicts-v1-0-bf17f9f0e23a@pengutronix.de> References: <20260601-debug-ll-conflicts-v1-0-bf17f9f0e23a@pengutronix.de> Message-ID: <20260601-debug-ll-conflicts-v1-3-bf17f9f0e23a@pengutronix.de> pl011.h is mainly included from include/debug_ll.h to provide the PUTC_LL() implementation. It is also included by some boards to get debug_ll_pl011_putc(). If a board includes it and at the same time DEBUG_LL is enabled for another board we end up with conflicting definitions of PUTC_LL(). To prevent this add a #define DEFINE_PUTC_LL to include/debug_ll.h. A debug_ll.h file now may only provide PUTC_LL() when this define is set. Signed-off-by: Sascha Hauer --- include/debug_ll.h | 2 ++ include/debug_ll/pl011.h | 6 +----- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/include/debug_ll.h b/include/debug_ll.h index 1410783b73..4cab96fbc4 100644 --- a/include/debug_ll.h +++ b/include/debug_ll.h @@ -19,7 +19,9 @@ * this initialization. Depending on the PUTC_LL implementation the board might * also hang in PUTC_LL without proper initialization. */ +#define DEFINE_PUTC_LL #include +#undef DEFINE_PUTC_LL #endif #if defined (CONFIG_DEBUG_LL) diff --git a/include/debug_ll/pl011.h b/include/debug_ll/pl011.h index aeec456f20..bded6720aa 100644 --- a/include/debug_ll/pl011.h +++ b/include/debug_ll/pl011.h @@ -16,11 +16,7 @@ static inline void debug_ll_pl011_putc(void __iomem *base, int c) writel(c, base + UART01x_DR); } -#ifdef CONFIG_DEBUG_LL - -#ifndef DEBUG_LL_UART_ADDR -#error DEBUG_LL_UART_ADDR is undefined! -#endif +#if defined(CONFIG_DEBUG_LL) && defined(DEFINE_PUTC_LL) static inline void PUTC_LL(char c) { -- 2.47.3 From s.hauer at pengutronix.de Mon Jun 1 05:29:53 2026 From: s.hauer at pengutronix.de (Sascha Hauer) Date: Mon, 01 Jun 2026 14:29:53 +0200 Subject: [PATCH 1/3] debug_ll: give PUTC_LL a common prototype In-Reply-To: <20260601-debug-ll-conflicts-v1-0-bf17f9f0e23a@pengutronix.de> References: <20260601-debug-ll-conflicts-v1-0-bf17f9f0e23a@pengutronix.de> Message-ID: <20260601-debug-ll-conflicts-v1-1-bf17f9f0e23a@pengutronix.de> Some PUTC_LL() implementations expect an integer as argument and others a char. For consistency change all to expect a char argument. Signed-off-by: Sascha Hauer --- arch/mips/mach-ath79/include/mach/debug_ll_ar9331.h | 2 +- arch/openrisc/include/asm/debug_ll.h | 2 +- arch/powerpc/include/asm/debug_ll.h | 2 +- include/mach/bcm283x/debug_ll.h | 4 ++-- include/mach/imx/debug_ll.h | 2 +- include/mach/k3/debug_ll.h | 2 +- include/mach/layerscape/debug_ll.h | 2 +- include/mach/mxs/debug_ll.h | 2 +- include/mach/omap/debug_ll.h | 2 +- include/mach/rockchip/debug_ll.h | 2 +- include/mach/stm32mp/debug_ll.h | 2 +- include/mach/zynq/debug_ll.h | 2 +- include/mach/zynqmp/debug_ll.h | 2 +- 13 files changed, 14 insertions(+), 14 deletions(-) diff --git a/arch/mips/mach-ath79/include/mach/debug_ll_ar9331.h b/arch/mips/mach-ath79/include/mach/debug_ll_ar9331.h index cd32e2d1d1..71978164c6 100644 --- a/arch/mips/mach-ath79/include/mach/debug_ll_ar9331.h +++ b/arch/mips/mach-ath79/include/mach/debug_ll_ar9331.h @@ -34,7 +34,7 @@ static inline u32 ar933x_debug_ll_readl(int offset) return __raw_readl((u8 *)DEBUG_LL_UART_ADDR + offset); } -static inline void PUTC_LL(int ch) +static inline void PUTC_LL(char ch) { u32 data; diff --git a/arch/openrisc/include/asm/debug_ll.h b/arch/openrisc/include/asm/debug_ll.h index 35d4360940..cd3b976e8a 100644 --- a/arch/openrisc/include/asm/debug_ll.h +++ b/arch/openrisc/include/asm/debug_ll.h @@ -26,7 +26,7 @@ static inline void debug_ll_init(void) /* already configured */ } -static inline void PUTC_LL(int c) +static inline void PUTC_LL(char c) { debug_ll_ns16550_putc(DEBUG_LL_UART_BASE, c); } diff --git a/arch/powerpc/include/asm/debug_ll.h b/arch/powerpc/include/asm/debug_ll.h index 910db2808d..0dc83b9cac 100644 --- a/arch/powerpc/include/asm/debug_ll.h +++ b/arch/powerpc/include/asm/debug_ll.h @@ -36,7 +36,7 @@ static inline void debug_ll_init(void) debug_ll_ns16550_init(DEBUG_LL_UART_BASE, divisor); } -static inline void PUTC_LL(int c) +static inline void PUTC_LL(char c) { debug_ll_ns16550_putc(DEBUG_LL_UART_BASE, c); } diff --git a/include/mach/bcm283x/debug_ll.h b/include/mach/bcm283x/debug_ll.h index 8bbff4fd9a..a6a3b8f088 100644 --- a/include/mach/bcm283x/debug_ll.h +++ b/include/mach/bcm283x/debug_ll.h @@ -70,7 +70,7 @@ static inline void debug_ll_init(void) debug_ll_ns16550_init(base, divisor); } -static inline void PUTC_LL(int c) +static inline void PUTC_LL(char c) { void __iomem *base = IOMEM(BCM2836_MINIUART_BASE); @@ -96,7 +96,7 @@ static inline void debug_ll_init(void) /* Configured by ROM */ } -static inline void PUTC_LL(int c) +static inline void PUTC_LL(char c) { void __iomem *base = IOMEM(BCM2711_MINIUART_BASE); diff --git a/include/mach/imx/debug_ll.h b/include/mach/imx/debug_ll.h index 05e16a8f02..0f6500fd2e 100644 --- a/include/mach/imx/debug_ll.h +++ b/include/mach/imx/debug_ll.h @@ -117,7 +117,7 @@ static inline void imx9_uart_setup_ll(void) lpuart32_setup(base + 0x10, 24000000); } -static inline void PUTC_LL(int c) +static inline void PUTC_LL(char c) { void __iomem *base = IOMEM(IMX_UART_BASE(IMX_DEBUG_SOC, CONFIG_DEBUG_IMX_UART_PORT)); diff --git a/include/mach/k3/debug_ll.h b/include/mach/k3/debug_ll.h index 13321c6134..acbe6c230b 100644 --- a/include/mach/k3/debug_ll.h +++ b/include/mach/k3/debug_ll.h @@ -41,7 +41,7 @@ static inline void debug_ll_init(void) /* already configured */ } -static inline void PUTC_LL(int c) +static inline void PUTC_LL(char c) { void __iomem *base = (void *)K3_UART_BASE(K3_DEBUG_SOC, CONFIG_DEBUG_K3_UART_PORT); diff --git a/include/mach/layerscape/debug_ll.h b/include/mach/layerscape/debug_ll.h index c54a4810a4..9c2e84dcf8 100644 --- a/include/mach/layerscape/debug_ll.h +++ b/include/mach/layerscape/debug_ll.h @@ -72,7 +72,7 @@ static inline void ls102xa_debug_ll_init(void) ls102xa_uart_setup(base); } -static inline void PUTC_LL(int c) +static inline void PUTC_LL(char c) { void __iomem *base = IOMEM(LS_UART_BASE(CONFIG_DEBUG_LAYERSCAPE_UART_PORT)); diff --git a/include/mach/mxs/debug_ll.h b/include/mach/mxs/debug_ll.h index 41658ba0c5..f38b1486a1 100644 --- a/include/mach/mxs/debug_ll.h +++ b/include/mach/mxs/debug_ll.h @@ -11,7 +11,7 @@ # define TXFE (1 << 7) # define TXFF (1 << 5) -static inline void PUTC_LL(int c) +static inline void PUTC_LL(char c) { void __iomem *base = (void *)IMX_DBGUART_BASE; diff --git a/include/mach/omap/debug_ll.h b/include/mach/omap/debug_ll.h index a95c1bf140..c0af1abac7 100644 --- a/include/mach/omap/debug_ll.h +++ b/include/mach/omap/debug_ll.h @@ -60,7 +60,7 @@ static inline void omap_debug_ll_init(void) debug_ll_write_reg(base, NS16550_MDR, 0); } -static inline void PUTC_LL(int c) +static inline void PUTC_LL(char c) { void __iomem *base = (void *)OMAP_UART_BASE(OMAP_DEBUG_SOC, CONFIG_DEBUG_OMAP_UART_PORT); diff --git a/include/mach/rockchip/debug_ll.h b/include/mach/rockchip/debug_ll.h index 941d1505e5..c2392d71e4 100644 --- a/include/mach/rockchip/debug_ll.h +++ b/include/mach/rockchip/debug_ll.h @@ -77,7 +77,7 @@ static inline void rockchip_debug_ll_init(void) debug_ll_ns16550_init(base, divisor); } -static inline void PUTC_LL(int c) +static inline void PUTC_LL(char c) { void __iomem *base = IOMEM(RK_UART_BASE(RK_DEBUG_SOC, CONFIG_DEBUG_ROCKCHIP_UART_PORT)); diff --git a/include/mach/stm32mp/debug_ll.h b/include/mach/stm32mp/debug_ll.h index 0d88910c13..c3ef3255c7 100644 --- a/include/mach/stm32mp/debug_ll.h +++ b/include/mach/stm32mp/debug_ll.h @@ -28,7 +28,7 @@ static inline void stm32_serial_putc(void *ctx, int c) while ((readl(base + ISR_OFFSET) & USART_ISR_TXE) == 0); } -static inline void PUTC_LL(int c) +static inline void PUTC_LL(char c) { stm32_serial_putc(IOMEM(DEBUG_LL_UART_ADDR), c); } diff --git a/include/mach/zynq/debug_ll.h b/include/mach/zynq/debug_ll.h index 3105211c1b..1d322a6aa4 100644 --- a/include/mach/zynq/debug_ll.h +++ b/include/mach/zynq/debug_ll.h @@ -23,7 +23,7 @@ #define ZYNQ_UART_STS_TFUL (1 << 4) #define ZYNQ_UART_TXDIS (1 << 5) -static inline void PUTC_LL(int c) +static inline void PUTC_LL(char c) { void __iomem *base = (void __iomem *)ZYNQ_DEBUG_LL_UART_BASE; diff --git a/include/mach/zynqmp/debug_ll.h b/include/mach/zynqmp/debug_ll.h index cc94d3ce54..c9e9547812 100644 --- a/include/mach/zynqmp/debug_ll.h +++ b/include/mach/zynqmp/debug_ll.h @@ -28,7 +28,7 @@ static inline void cdns_serial_putc(void *ctx, int c) writel(c, base + 0x30); } -static inline void PUTC_LL(int c) +static inline void PUTC_LL(char c) { cdns_serial_putc(IOMEM(ZYNQMP_DEBUG_LL_UART_BASE), c); } -- 2.47.3 From s.hauer at pengutronix.de Mon Jun 1 05:29:54 2026 From: s.hauer at pengutronix.de (Sascha Hauer) Date: Mon, 01 Jun 2026 14:29:54 +0200 Subject: [PATCH 2/3] debug_ll: Add Kconfig options for debug uarts that have none In-Reply-To: <20260601-debug-ll-conflicts-v1-0-bf17f9f0e23a@pengutronix.de> References: <20260601-debug-ll-conflicts-v1-0-bf17f9f0e23a@pengutronix.de> Message-ID: <20260601-debug-ll-conflicts-v1-2-bf17f9f0e23a@pengutronix.de> Some SoCs include its debug_ll.h header file only by testing if support for that SoC is compiled in. That doesn't work when barebox is built for multiple SoCs as this leads to multiple definitions of PUTC_LL. Add a debug UART Kconfig option for all SoCs that do not yet have one. The debug UART selection is a choice which makes sure only a single debug UART is selected which also means we can include the SoC specific debug_ll.h files using #if defined / elif defined. Signed-off-by: Sascha Hauer --- arch/arm/include/asm/debug_ll.h | 69 ++++++++++++++--------------------------- common/Kconfig.debug_ll | 28 +++++++++++++++++ 2 files changed, 52 insertions(+), 45 deletions(-) diff --git a/arch/arm/include/asm/debug_ll.h b/arch/arm/include/asm/debug_ll.h index fd7715c743..a645a6e910 100644 --- a/arch/arm/include/asm/debug_ll.h +++ b/arch/arm/include/asm/debug_ll.h @@ -3,66 +3,45 @@ #ifndef __ASM_DEBUG_LL_H__ #define __ASM_DEBUG_LL_H__ -#ifdef CONFIG_DEBUG_IMX_UART +#if defined CONFIG_DEBUG_IMX_UART #include -#endif - -#ifdef CONFIG_DEBUG_ROCKCHIP_UART +#elif defined CONFIG_DEBUG_ROCKCHIP_UART #include -#endif - -#ifdef CONFIG_DEBUG_OMAP_UART +#elif defined CONFIG_DEBUG_OMAP_UART #include -#endif - -#ifdef CONFIG_DEBUG_ZYNQMP_UART +#elif defined CONFIG_DEBUG_ZYNQMP_UART #include -#endif - -#ifdef CONFIG_DEBUG_STM32MP_UART +#elif defined CONFIG_DEBUG_STM32MP_UART #include -#endif - -#if defined(CONFIG_DEBUG_VEXPRESS_UART) || \ - defined(CONFIG_DEBUG_QEMU_ARM32_VIRT) +#elif defined CONFIG_DEBUG_VEXPRESS_UART || defined CONFIG_DEBUG_QEMU_ARM32_VIRT #include -#endif - -#ifdef CONFIG_DEBUG_BCM283X_UART +#elif defined CONFIG_DEBUG_BCM283X_UART #include -#endif - -#ifdef CONFIG_DEBUG_LAYERSCAPE_UART +#elif defined CONFIG_DEBUG_LAYERSCAPE_UART #include -#endif - -#ifdef CONFIG_DEBUG_SEMIHOSTING +#elif defined CONFIG_DEBUG_SEMIHOSTING #include -#endif - -#ifdef CONFIG_DEBUG_QEMU_ARM64_VIRT +#elif defined CONFIG_DEBUG_AT91_UART +#include +#elif defined CONFIG_DEBUG_QEMU_ARM64_VIRT #define DEBUG_LL_UART_ADDR 0x9000000 #include -#elif defined CONFIG_ARCH_MVEBU +#elif defined CONFIG_DEBUG_AM62X_UART +#include +#elif defined CONFIG_DEBUG_MVEBU_UART #include -#elif defined CONFIG_ARCH_ZYNQ -#include -#elif defined CONFIG_ARCH_VERSATILE +#elif defined CONFIG_DEBUG_CLPS711X_UART +#include +#elif defined CONFIG_DEBUG_MXS_UART +#include +#elif defined CONFIG_DEBUG_VERSATILE_UART #include -#elif defined CONFIG_ARCH_TEGRA +#elif defined CONFIG_DEBUG_TEGRA_UART #include -#elif defined CONFIG_ARCH_SOCFPGA +#elif defined CONFIG_DEBUG_ZYNQ_UART +#include +#elif defined CONFIG_DEBUG_SOCFPGA_UART #include -#elif defined CONFIG_ARCH_PXA -#include -#elif defined CONFIG_ARCH_MXS -#include -#elif defined CONFIG_ARCH_CLPS711X -#include -#elif defined CONFIG_ARCH_AT91 -#include -#elif defined CONFIG_ARCH_K3 -#include #endif #endif diff --git a/common/Kconfig.debug_ll b/common/Kconfig.debug_ll index 715b1978f8..3f06e2eef4 100644 --- a/common/Kconfig.debug_ll +++ b/common/Kconfig.debug_ll @@ -312,6 +312,10 @@ config DEBUG_RPI4_MINI_UART Say Y here if you want low-level debugging support on RaspberryPi 4 board mini UART. +config DEBUG_ZYNQ_UART + bool "Zynq debug UART" + depends on ARCH_ZYNQ + config DEBUG_ZYNQMP_UART bool "Zynqmp Debug UART" depends on ARCH_ZYNQMP @@ -390,6 +394,30 @@ config DEBUG_OPENRISC_NS16550 bool "OpenRISC NS16550 console" depends on OPENRISC +config DEBUG_MVEBU_UART + bool "mvebu console" + depends on ARCH_MVEBU + +config DEBUG_CLPS711X_UART + bool "CLPS711x debug UART" + depends on ARCH_CLPS711X + +config DEBUG_MXS_UART + bool "MXS debug UART" + depends on ARCH_MXS + +config DEBUG_VERSATILE_UART + bool "Versatile debug UART" + depends on ARCH_VERSATILE + +config DEBUG_TEGRA_UART + bool "Tegra debug UART" + depends on ARCH_TEGRA + +config DEBUG_SOCFPGA_UART + bool "SoCFPGA debug UART" + depends on ARCH_SOCFPGA + endchoice config DEBUG_LL_NS16550 -- 2.47.3 From johannes.schneider at leica-geosystems.com Mon Jun 1 19:24:09 2026 From: johannes.schneider at leica-geosystems.com (Johannes Schneider) Date: Tue, 2 Jun 2026 02:24:09 +0000 Subject: [PATCH] lib: gui: png_pico: fix use-after-free and double-free in png_open Message-ID: <20260602022409.316585-1-johannes.schneider@leica-geosystems.com> From: Thomas Haemmerle png_alloc_free_all() frees all picopng-internal allocations, including the image->data buffer. The previous code stored a pointer to this buffer in img->data and called png_alloc_free_all() ? leaving img->data as a dangling pointer. The subsequent png_close()'s free(img->data) then performed a double-free on already-freed memory, causing a crash or heap corruption when displaying the boot logo. Fix by copying the decoded pixel data into a fresh malloc buffer before calling png_alloc_free_all(). png_close() correctly frees this copy. Assisted-by: Claude:claude-sonnet-4-6 Signed-of-by: Thomas Haemmerle --- lib/gui/png_pico.c | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/lib/gui/png_pico.c b/lib/gui/png_pico.c index 029fee2a40..8d70521b46 100644 --- a/lib/gui/png_pico.c +++ b/lib/gui/png_pico.c @@ -46,6 +46,8 @@ struct image *png_open(char *inbuf, int insize) { PNG_info_t *png_info; int ret; + size_t imgsize; + void *imgcopy; struct image *img = calloc(1, sizeof(struct image)); if (!img) @@ -67,12 +69,27 @@ struct image *png_open(char *inbuf, int insize) img->width = png_info->width; img->height = png_info->height; img->bits_per_pixel = 4 << 3; - img->data = png_info->image->data; - pr_debug("png: %d x %d data at 0x%p\n", img->width, img->height, img->data); + /* + * Copy decoded pixels to a stable buffer before png_alloc_free_all() + * frees the picopng internal allocations (including image->data). + * Without this copy, img->data would be a dangling pointer and + * png_close()'s free(img->data) would be a double-free. + */ + imgsize = png_info->width * png_info->height * 4; + imgcopy = malloc(imgsize); + if (!imgcopy) { + ret = -ENOMEM; + goto err; + } + memcpy(imgcopy, png_info->image->data, imgsize); png_alloc_free_all(); + img->data = imgcopy; + + pr_debug("png: %d x %d data at 0x%p\n", img->width, img->height, img->data); + return img; err: png_alloc_free_all(); -- 2.43.0