Buffer overflow / memory corruption in TH1520 AON RPC message construction

HIGH
torvalds/linux
Commit: d58305b2dbe3
Affected: 7.0-rc6 and earlier (upstream 7.x where TH1520 AON RPC is present)
2026-04-11 08:02 UTC

Description

The commit fixes a buffer overflow in the TH1520 AON RPC handling path (drivers/firmware/thead,th1520-aon.c). Previously, the code built the RPC message by using the RPC_SET_BE16 macro to write 16-bit values into the message at specific offsets, which could write beyond the intended bounds and corrupt memory. The patch replaces these writes with direct 16-bit fields (resource and mode) updated using cpu_to_be16, aligning the payload with the actual RPC structure and preventing out-of-bounds writes. This addresses a potential memory corruption vulnerability in the TH1520 AON firmware RPC path. The change also updates the endian handling macros in the header to standardize usage.

Commit Details

Author: Linus Torvalds

Date: 2026-04-09 18:09 UTC

Message:

Merge tag 'pmdomain-v7.0-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/linux-pm Pull pmdomain fixes from Ulf Hansson: - imx: Prevent hang at power down for imx8mp-blk-ctrl - thead: Fix buffer overflow for TH1520 AON driver - Change Ulf Hansson's email * tag 'pmdomain-v7.0-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/linux-pm: MAINTAINERS, mailmap: Change Ulf Hansson's email pmdomain: imx8mp-blk-ctrl: Keep the NOC_HDCP clock enabled firmware: thead: Fix buffer overflow and use standard endian macros

Triage Assessment

Vulnerability Type: Buffer Overflow

Confidence: HIGH

Reasoning:

Commit message explicitly states: 'firmware: thead: Fix buffer overflow and use standard endian macros'. Diff shows a change in th1520-aon message handling to use correct endianness and fields, which prevents a potential buffer overflow in RPC/message handling.

Verification Assessment

Vulnerability Type: Buffer overflow / memory corruption in TH1520 AON RPC message construction

Confidence: HIGH

Affected Versions: 7.0-rc6 and earlier (upstream 7.x where TH1520 AON RPC is present)

Code Diff

diff --git a/.mailmap b/.mailmap index 2d04aeba68b40b..22c5ab1c5d55cb 100644 --- a/.mailmap +++ b/.mailmap @@ -849,6 +849,8 @@ Tvrtko Ursulin <tursulin@ursulin.net> <tvrtko.ursulin@onelan.co.uk> Tvrtko Ursulin <tursulin@ursulin.net> <tvrtko@ursulin.net> Tycho Andersen <tycho@tycho.pizza> <tycho@tycho.ws> Tzung-Bi Shih <tzungbi@kernel.org> <tzungbi@google.com> +Ulf Hansson <ulfh@kernel.org> <ulf.hansson@linaro.org> +Ulf Hansson <ulfh@kernel.org> <ulf.hansson@stericsson.com> Umang Jain <uajain@igalia.com> <umang.jain@ideasonboard.com> Uwe Kleine-König <ukleinek@informatik.uni-freiburg.de> Uwe Kleine-König <u.kleine-koenig@baylibre.com> <ukleinek@baylibre.com> diff --git a/MAINTAINERS b/MAINTAINERS index dc935838e51619..d238590a31f207 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -6717,7 +6717,7 @@ F: include/linux/platform_data/cpuidle-exynos.h CPUIDLE DRIVER - ARM PSCI M: Lorenzo Pieralisi <lpieralisi@kernel.org> M: Sudeep Holla <sudeep.holla@kernel.org> -M: Ulf Hansson <ulf.hansson@linaro.org> +M: Ulf Hansson <ulfh@kernel.org> L: linux-pm@vger.kernel.org L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) S: Supported @@ -6725,7 +6725,7 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/linux-pm.git F: drivers/cpuidle/cpuidle-psci.c CPUIDLE DRIVER - ARM PSCI PM DOMAIN -M: Ulf Hansson <ulf.hansson@linaro.org> +M: Ulf Hansson <ulfh@kernel.org> L: linux-pm@vger.kernel.org L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) S: Supported @@ -6734,7 +6734,7 @@ F: drivers/cpuidle/cpuidle-psci-domain.c F: drivers/cpuidle/cpuidle-psci.h CPUIDLE DRIVER - DT IDLE PM DOMAIN -M: Ulf Hansson <ulf.hansson@linaro.org> +M: Ulf Hansson <ulfh@kernel.org> L: linux-pm@vger.kernel.org S: Supported T: git git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/linux-pm.git @@ -10730,7 +10730,7 @@ F: Documentation/devicetree/bindings/i2c/i2c-demux-pinctrl.yaml F: drivers/i2c/muxes/i2c-demux-pinctrl.c GENERIC PM DOMAINS -M: Ulf Hansson <ulf.hansson@linaro.org> +M: Ulf Hansson <ulfh@kernel.org> L: linux-pm@vger.kernel.org S: Supported F: Documentation/devicetree/bindings/power/power?domain* @@ -18090,7 +18090,7 @@ F: drivers/mmc/host/mmc_spi.c F: include/linux/spi/mmc_spi.h MULTIMEDIA CARD (MMC), SECURE DIGITAL (SD) AND SDIO SUBSYSTEM -M: Ulf Hansson <ulf.hansson@linaro.org> +M: Ulf Hansson <ulfh@kernel.org> L: linux-mmc@vger.kernel.org S: Maintained T: git git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/mmc.git @@ -24696,7 +24696,7 @@ F: drivers/media/i2c/imx415.c SONY MEMORYSTICK SUBSYSTEM M: Maxim Levitsky <maximlevitsky@gmail.com> M: Alex Dubov <oakad@yahoo.com> -M: Ulf Hansson <ulf.hansson@linaro.org> +M: Ulf Hansson <ulfh@kernel.org> L: linux-mmc@vger.kernel.org S: Maintained T: git git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/mmc.git @@ -27615,7 +27615,7 @@ F: Documentation/fb/uvesafb.rst F: drivers/video/fbdev/uvesafb.* Ux500 CLOCK DRIVERS -M: Ulf Hansson <ulf.hansson@linaro.org> +M: Ulf Hansson <ulfh@kernel.org> L: linux-clk@vger.kernel.org L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) S: Maintained diff --git a/drivers/firmware/thead,th1520-aon.c b/drivers/firmware/thead,th1520-aon.c index a35fd5e2a07f6c..d7f19b5b5f468c 100644 --- a/drivers/firmware/thead,th1520-aon.c +++ b/drivers/firmware/thead,th1520-aon.c @@ -170,10 +170,9 @@ int th1520_aon_power_update(struct th1520_aon_chan *aon_chan, u16 rsrc, hdr->func = TH1520_AON_PM_FUNC_SET_RESOURCE_POWER_MODE; hdr->size = TH1520_AON_RPC_MSG_NUM; - RPC_SET_BE16(&msg.resource, 0, rsrc); - RPC_SET_BE16(&msg.resource, 2, - (power_on ? TH1520_AON_PM_PW_MODE_ON : - TH1520_AON_PM_PW_MODE_OFF)); + msg.resource = cpu_to_be16(rsrc); + msg.mode = cpu_to_be16(power_on ? TH1520_AON_PM_PW_MODE_ON : + TH1520_AON_PM_PW_MODE_OFF); ret = th1520_aon_call_rpc(aon_chan, &msg); if (ret) diff --git a/drivers/pmdomain/imx/imx8mp-blk-ctrl.c b/drivers/pmdomain/imx/imx8mp-blk-ctrl.c index 8fc79f9723f07e..3f5b9499d30a0c 100644 --- a/drivers/pmdomain/imx/imx8mp-blk-ctrl.c +++ b/drivers/pmdomain/imx/imx8mp-blk-ctrl.c @@ -352,9 +352,6 @@ static void imx8mp_hdmi_blk_ctrl_power_on(struct imx8mp_blk_ctrl *bc, regmap_set_bits(bc->regmap, HDMI_RTX_RESET_CTL0, BIT(12)); regmap_clear_bits(bc->regmap, HDMI_TX_CONTROL0, BIT(3)); break; - case IMX8MP_HDMIBLK_PD_HDCP: - regmap_set_bits(bc->regmap, HDMI_RTX_CLK_CTL0, BIT(11)); - break; case IMX8MP_HDMIBLK_PD_HRV: regmap_set_bits(bc->regmap, HDMI_RTX_CLK_CTL1, BIT(3) | BIT(4) | BIT(5)); regmap_set_bits(bc->regmap, HDMI_RTX_RESET_CTL0, BIT(15)); @@ -408,9 +405,6 @@ static void imx8mp_hdmi_blk_ctrl_power_off(struct imx8mp_blk_ctrl *bc, regmap_clear_bits(bc->regmap, HDMI_RTX_CLK_CTL0, BIT(7)); regmap_clear_bits(bc->regmap, HDMI_RTX_CLK_CTL1, BIT(22) | BIT(24)); break; - case IMX8MP_HDMIBLK_PD_HDCP: - regmap_clear_bits(bc->regmap, HDMI_RTX_CLK_CTL0, BIT(11)); - break; case IMX8MP_HDMIBLK_PD_HRV: regmap_clear_bits(bc->regmap, HDMI_RTX_RESET_CTL0, BIT(15)); regmap_clear_bits(bc->regmap, HDMI_RTX_CLK_CTL1, BIT(3) | BIT(4) | BIT(5)); @@ -439,7 +433,7 @@ static int imx8mp_hdmi_power_notifier(struct notifier_block *nb, regmap_write(bc->regmap, HDMI_RTX_CLK_CTL0, 0x0); regmap_write(bc->regmap, HDMI_RTX_CLK_CTL1, 0x0); regmap_set_bits(bc->regmap, HDMI_RTX_CLK_CTL0, - BIT(0) | BIT(1) | BIT(10)); + BIT(0) | BIT(1) | BIT(10) | BIT(11)); regmap_set_bits(bc->regmap, HDMI_RTX_RESET_CTL0, BIT(0)); /* diff --git a/include/linux/firmware/thead/thead,th1520-aon.h b/include/linux/firmware/thead/thead,th1520-aon.h index dae132b66873a8..d81f5f6f5b905a 100644 --- a/include/linux/firmware/thead/thead,th1520-aon.h +++ b/include/linux/firmware/thead/thead,th1520-aon.h @@ -97,80 +97,6 @@ struct th1520_aon_rpc_ack_common { #define RPC_GET_SVC_FLAG_ACK_TYPE(MESG) (((MESG)->svc & 0x40) >> 6) #define RPC_SET_SVC_FLAG_ACK_TYPE(MESG, ACK) ((MESG)->svc |= (ACK) << 6) -#define RPC_SET_BE64(MESG, OFFSET, SET_DATA) \ - do { \ - u8 *data = (u8 *)(MESG); \ - u64 _offset = (OFFSET); \ - u64 _set_data = (SET_DATA); \ - data[_offset + 7] = _set_data & 0xFF; \ - data[_offset + 6] = (_set_data & 0xFF00) >> 8; \ - data[_offset + 5] = (_set_data & 0xFF0000) >> 16; \ - data[_offset + 4] = (_set_data & 0xFF000000) >> 24; \ - data[_offset + 3] = (_set_data & 0xFF00000000) >> 32; \ - data[_offset + 2] = (_set_data & 0xFF0000000000) >> 40; \ - data[_offset + 1] = (_set_data & 0xFF000000000000) >> 48; \ - data[_offset + 0] = (_set_data & 0xFF00000000000000) >> 56; \ - } while (0) - -#define RPC_SET_BE32(MESG, OFFSET, SET_DATA) \ - do { \ - u8 *data = (u8 *)(MESG); \ - u64 _offset = (OFFSET); \ - u64 _set_data = (SET_DATA); \ - data[_offset + 3] = (_set_data) & 0xFF; \ - data[_offset + 2] = (_set_data & 0xFF00) >> 8; \ - data[_offset + 1] = (_set_data & 0xFF0000) >> 16; \ - data[_offset + 0] = (_set_data & 0xFF000000) >> 24; \ - } while (0) - -#define RPC_SET_BE16(MESG, OFFSET, SET_DATA) \ - do { \ - u8 *data = (u8 *)(MESG); \ - u64 _offset = (OFFSET); \ - u64 _set_data = (SET_DATA); \ - data[_offset + 1] = (_set_data) & 0xFF; \ - data[_offset + 0] = (_set_data & 0xFF00) >> 8; \ - } while (0) - -#define RPC_SET_U8(MESG, OFFSET, SET_DATA) \ - do { \ - u8 *data = (u8 *)(MESG); \ - data[OFFSET] = (SET_DATA) & 0xFF; \ - } while (0) - -#define RPC_GET_BE64(MESG, OFFSET, PTR) \ - do { \ - u8 *data = (u8 *)(MESG); \ - u64 _offset = (OFFSET); \ - *(u32 *)(PTR) = \ - (data[_offset + 7] | data[_offset + 6] << 8 | \ - data[_offset + 5] << 16 | data[_offset + 4] << 24 | \ - data[_offset + 3] << 32 | data[_offset + 2] << 40 | \ - data[_offset + 1] << 48 | data[_offset + 0] << 56); \ - } while (0) - -#define RPC_GET_BE32(MESG, OFFSET, PTR) \ - do { \ - u8 *data = (u8 *)(MESG); \ - u64 _offset = (OFFSET); \ - *(u32 *)(PTR) = \ - (data[_offset + 3] | data[_offset + 2] << 8 | \ - data[_offset + 1] << 16 | data[_offset + 0] << 24); \ - } while (0) - -#define RPC_GET_BE16(MESG, OFFSET, PTR) \ - do { \ - u8 *data = (u8 *)(MESG); \ - u64 _offset = (OFFSET); \ - *(u16 *)(PTR) = (data[_offset + 1] | data[_offset + 0] << 8); \ - } while (0) - -#define RPC_GET_U8(MESG, OFFSET, PTR) \ - do { \ - u8 *data = (u8 *)(MESG); \ - *(u8 *)(PTR) = (data[OFFSET]); \ - } while (0) - /* * Defines for SC PM Power Mode */
← Back to Alerts View on GitHub →