From fea64ee9adbc6c4939b593201f6df7189d345b4f Mon Sep 17 00:00:00 2001 From: Dom Cobley Date: Wed, 26 Aug 2026 11:10:36 +0100 Subject: [PATCH] drm/vc4: hdmi: Don't write past the end of a packet RAM slot Each packet RAM slot is VC4_HDMI_PACKET_STRIDE (36) bytes: nine 32-bit words holding a 3-byte packet header followed by four 7-byte subpackets. The even words carry three bytes and the odd words four, so a slot can only ever hold 31 bytes of infoframe. vc4_hdmi_write_infoframe() instead loops over the infoframe seven bytes at a time and emits two words per iteration, consuming ceil(len / 7) * 8 bytes of RAM. For any infoframe longer than 28 bytes that is more than the slot holds, and the trailing write lands on the first word of the next slot. The subsequent loop that clears the remainder of the slot is skipped as well, since packet_reg has already passed packet_reg_next. Today the only infoframe large enough to trigger this is the 30-byte Dynamic Range and Mastering infoframe, which occupies slot 7 and spills into slot 8, so nothing observable happens. A full-length (31-byte) vendor infoframe would occupy slot 1 and zero the header word of slot 2, corrupting the AVI infoframe written just before it. Stop the loop once the slot is full, and reject infoframes that cannot fit rather than silently truncating them. The limit matches the largest infoframe hdmi_infoframe_pack() can produce, HDMI_INFOFRAME_HEADER_SIZE + HDMI_MAX_INFOFRAME_SIZE, so no valid caller is affected. Signed-off-by: Dom Cobley --- drivers/gpu/drm/vc4/vc4_hdmi.c | 5 ++++- drivers/gpu/drm/vc4/vc4_hdmi_regs.h | 6 ++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c index 5833a6997fd66b..074afabaf08441 100644 --- a/drivers/gpu/drm/vc4/vc4_hdmi.c +++ b/drivers/gpu/drm/vc4/vc4_hdmi.c @@ -654,7 +654,7 @@ static int vc4_hdmi_write_infoframe(struct drm_connector *connector, if (!drm_dev_enter(drm, &idx)) return 0; - if (len > sizeof(buffer)) { + if (len > VC4_HDMI_PACKET_SIZE) { ret = -ENOMEM; goto out; } @@ -680,6 +680,9 @@ static int vc4_hdmi_write_infoframe(struct drm_connector *connector, base + packet_reg); packet_reg += 4; + if (packet_reg >= packet_reg_next) + break; + writel(buffer[i + 3] << 0 | buffer[i + 4] << 8 | buffer[i + 5] << 16 | diff --git a/drivers/gpu/drm/vc4/vc4_hdmi_regs.h b/drivers/gpu/drm/vc4/vc4_hdmi_regs.h index 59bfd69f54d980..fb97e8a72b59f8 100644 --- a/drivers/gpu/drm/vc4/vc4_hdmi_regs.h +++ b/drivers/gpu/drm/vc4/vc4_hdmi_regs.h @@ -7,6 +7,12 @@ #define VC4_HDMI_PACKET_STRIDE 0x24 +/* + * A packet RAM slot is 9 words, holding a 3-byte packet header followed by + * four 7-byte subpackets, so only 31 of its 36 bytes are addressable. + */ +#define VC4_HDMI_PACKET_SIZE 31 + enum vc4_hdmi_regs { VC4_INVALID = 0, VC4_HDMI,