AMD General

Reviewed-by: Asad Kamal <[email protected]>

Thanks & Regards
Asad

-----Original Message-----
From: Lazar, Lijo <[email protected]>
Sent: Friday, June 19, 2026 6:47 PM
To: [email protected]
Cc: Zhang, Hawking <[email protected]>; Deucher, Alexander 
<[email protected]>; Kamal, Asad <[email protected]>; Li, Candice 
<[email protected]>; Kasiviswanathan, Harish <[email protected]>; 
Deucher, Alexander <[email protected]>
Subject: [PATCH v2] drm/amdgpu: bounds check ATOM IIO table parsing

atom_index_iio() parsed the IIO bytecode without bounds checks, allowing 
out-of-bounds reads on a malformed VBIOS. Pass the BIOS size into
amdgpu_atom_parse() and bound the parse loops by it.

Signed-off-by: Lijo Lazar <[email protected]>
Assisted-by: Claude Code
Reviewed-by: Alex Deucher <[email protected]>
---
v2: check bios size also before indexing offset (Asad)

 drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c |  2 +-
 drivers/gpu/drm/amd/amdgpu/atom.c            | 25 ++++++++++++++++----
 drivers/gpu/drm/amd/amdgpu/atom.h            |  3 ++-
 3 files changed, 23 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c
index ca65e6ebdb25..a0c740bce310 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c
@@ -1923,7 +1923,7 @@ int amdgpu_atombios_init(struct amdgpu_device *adev)
        atom_card_info->pll_read = cail_pll_read;
        atom_card_info->pll_write = cail_pll_write;

-       adev->mode_info.atom_context = amdgpu_atom_parse(atom_card_info, 
adev->bios);
+       adev->mode_info.atom_context = amdgpu_atom_parse(atom_card_info,
+adev->bios, adev->bios_size);
        if (!adev->mode_info.atom_context) {
                amdgpu_atombios_fini(adev);
                return -ENOMEM;
diff --git a/drivers/gpu/drm/amd/amdgpu/atom.c 
b/drivers/gpu/drm/amd/amdgpu/atom.c
index a40ce7555f28..0d5be1795972 100644
--- a/drivers/gpu/drm/amd/amdgpu/atom.c
+++ b/drivers/gpu/drm/amd/amdgpu/atom.c
@@ -1327,11 +1327,25 @@ static void atom_index_iio(struct atom_context *ctx, 
int base)
        ctx->iio = kzalloc(2 * 256, GFP_KERNEL);
        if (!ctx->iio)
                return;
-       while (CU8(base) == ATOM_IIO_START) {
-               ctx->iio[CU8(base + 1)] = base + 2;
+       while (base + 1 < ctx->bios_size && CU8(base) == ATOM_IIO_START) {
+               uint8_t index = CU8(base + 1);
+               int start = base + 2;
                base += 2;
-               while (CU8(base) != ATOM_IIO_END)
-                       base += atom_iio_len[CU8(base)];
+               while (base < ctx->bios_size && CU8(base) != ATOM_IIO_END) {
+                       uint8_t op = CU8(base);
+
+                       /*
+                        * Unknown opcode: its length is unknown so the byte
+                        * stream cannot be resynced reliably.
+                        */
+                       if (op >= ARRAY_SIZE(atom_iio_len))
+                               return;
+                       base += atom_iio_len[op];
+               }
+               if (base >= ctx->bios_size)
+                       return;
+               /* Only index well-formed methods, others stay 0 */
+               ctx->iio[index] = start;
                base += 3;
        }
 }
@@ -1553,7 +1567,7 @@ static inline void atom_print_vbios_info(struct 
atom_context *ctx)
                drm_info(ctx->card->dev, "ATOM BIOS: %s\n", vbios_info);  }

-struct atom_context *amdgpu_atom_parse(struct card_info *card, void *bios)
+struct atom_context *amdgpu_atom_parse(struct card_info *card, void
+*bios, uint32_t bios_size)
 {
        int base;
        struct atom_context *ctx =
@@ -1567,6 +1581,7 @@ struct atom_context *amdgpu_atom_parse(struct card_info 
*card, void *bios)

        ctx->card = card;
        ctx->bios = bios;
+       ctx->bios_size = bios_size;

        if (CU16(0) != ATOM_BIOS_MAGIC) {
                pr_info("Invalid BIOS magic\n");
diff --git a/drivers/gpu/drm/amd/amdgpu/atom.h 
b/drivers/gpu/drm/amd/amdgpu/atom.h
index bb3d9eb7eb6b..4687c019cbe3 100644
--- a/drivers/gpu/drm/amd/amdgpu/atom.h
+++ b/drivers/gpu/drm/amd/amdgpu/atom.h
@@ -133,6 +133,7 @@ struct atom_context {
        struct card_info *card;
        struct mutex mutex;
        void *bios;
+       uint32_t bios_size;
        uint32_t cmd_table, data_table;
        uint16_t *iio;

@@ -160,7 +161,7 @@ struct atom_context {

 extern int amdgpu_atom_debug;

-struct atom_context *amdgpu_atom_parse(struct card_info *card, void *bios);
+struct atom_context *amdgpu_atom_parse(struct card_info *card, void
+*bios, uint32_t bios_size);
 int amdgpu_atom_execute_table(struct atom_context *ctx, int index, uint32_t 
*params, int params_size);  int amdgpu_atom_asic_init(struct atom_context 
*ctx);  void amdgpu_atom_destroy(struct atom_context *ctx);
--
2.49.0

Reply via email to