Skip to content

Commit d1691bb

Browse files
lucasdemarchijlahtine-intel
authored andcommitted
drm/i915/gt: Avoid out-of-bounds access when loading HuC
When HuC is loaded by GSC, there is no header definition for the kernel to look at and firmware is just handed to GSC. However when reading the version, it should still check the size of the blob to guarantee it's not incurring into out-of-bounds array access. If firmware is smaller than expected, the following message is now printed: # echo boom > /lib/firmware/i915/dg2_huc_gsc.bin # dmesg | grep -i huc [drm] GT0: HuC firmware i915/dg2_huc_gsc.bin: invalid size: 5 < 184 [drm] *ERROR* GT0: HuC firmware i915/dg2_huc_gsc.bin: fetch failed -ENODATA ... Even without this change the size, header and signature are still checked by GSC when loading, so this only avoids the out-of-bounds array access. Fixes: a7b516b ("drm/i915/huc: Add fetch support for gsc-loaded HuC binary") Cc: Daniele Ceraolo Spurio <[email protected]> Cc: Alan Previn <[email protected]> Signed-off-by: Lucas De Marchi <[email protected]> Reviewed-by: Daniele Ceraolo Spurio <[email protected]> Link: https://patchwork.freedesktop.org/patch/msgid/[email protected] (cherry picked from commit adfbae9) Signed-off-by: Joonas Lahtinen <[email protected]>
1 parent 2efc8e1 commit d1691bb

File tree

1 file changed

+17
-4
lines changed

1 file changed

+17
-4
lines changed

drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -488,12 +488,25 @@ static void __force_fw_fetch_failures(struct intel_uc_fw *uc_fw, int e)
488488
}
489489
}
490490

491-
static int check_gsc_manifest(const struct firmware *fw,
491+
static int check_gsc_manifest(struct intel_gt *gt,
492+
const struct firmware *fw,
492493
struct intel_uc_fw *uc_fw)
493494
{
494495
u32 *dw = (u32 *)fw->data;
495-
u32 version_hi = dw[HUC_GSC_VERSION_HI_DW];
496-
u32 version_lo = dw[HUC_GSC_VERSION_LO_DW];
496+
u32 version_hi, version_lo;
497+
size_t min_size;
498+
499+
/* Check the size of the blob before examining buffer contents */
500+
min_size = sizeof(u32) * (HUC_GSC_VERSION_LO_DW + 1);
501+
if (unlikely(fw->size < min_size)) {
502+
gt_warn(gt, "%s firmware %s: invalid size: %zu < %zu\n",
503+
intel_uc_fw_type_repr(uc_fw->type), uc_fw->file_selected.path,
504+
fw->size, min_size);
505+
return -ENODATA;
506+
}
507+
508+
version_hi = dw[HUC_GSC_VERSION_HI_DW];
509+
version_lo = dw[HUC_GSC_VERSION_LO_DW];
497510

498511
uc_fw->file_selected.ver.major = FIELD_GET(HUC_GSC_MAJOR_VER_HI_MASK, version_hi);
499512
uc_fw->file_selected.ver.minor = FIELD_GET(HUC_GSC_MINOR_VER_HI_MASK, version_hi);
@@ -664,7 +677,7 @@ static int check_fw_header(struct intel_gt *gt,
664677
return 0;
665678

666679
if (uc_fw->loaded_via_gsc)
667-
err = check_gsc_manifest(fw, uc_fw);
680+
err = check_gsc_manifest(gt, fw, uc_fw);
668681
else
669682
err = check_ccs_header(gt, fw, uc_fw);
670683
if (err)

0 commit comments

Comments
 (0)