On Sat, Oct 17, 2026 at 2:26 PM Jiale Yao <[email protected]> wrote: > > The KFD SRAT walker reads the first subtable length without checking > that a header is present and trusts subsequent lengths when accessing > CPU and generic affinity records. Invalid firmware lengths can therefore > cause out-of-bounds reads. > > Validate the table header, every generic subtable range, and each > supported typed record before reading its fields. > > Signed-off-by: Jiale Yao <[email protected]>
Reviewed-by: Alex Deucher <[email protected]> and applied. Thanks! > --- > drivers/gpu/drm/amd/amdkfd/kfd_crat.c | 35 ++++++++++++++++++--------- > 1 file changed, 24 insertions(+), 11 deletions(-) > > diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_crat.c > b/drivers/gpu/drm/amd/amdkfd/kfd_crat.c > index 6e0df685503d..32d7573dffc9 100644 > --- a/drivers/gpu/drm/amd/amdkfd/kfd_crat.c > +++ b/drivers/gpu/drm/amd/amdkfd/kfd_crat.c > @@ -2056,27 +2056,33 @@ static void kfd_find_numa_node_in_srat(struct > kfd_node *kdev) > return; > } > > + if (table_header->length < sizeof(struct acpi_table_srat)) > + goto invalid_srat; > + > table_end = (unsigned long)table_header + table_header->length; > > /* Parse all entries looking for a match. */ > sub_header = (struct acpi_subtable_header *) > ((unsigned long)table_header + > sizeof(struct acpi_table_srat)); > - subtable_len = sub_header->length; > > - while (((unsigned long)sub_header) + subtable_len < table_end) { > - /* > - * If length is 0, break from this loop to avoid > - * infinite loop. > - */ > - if (subtable_len == 0) { > - pr_err("SRAT invalid zero length\n"); > - break; > - } > + while ((unsigned long)sub_header < table_end) { > + unsigned long start = (unsigned long)sub_header; > + > + if (table_end - start < sizeof(*sub_header)) > + goto invalid_srat; > + > + subtable_len = sub_header->length; > + if (subtable_len < sizeof(*sub_header) || > + subtable_len > table_end - start) > + goto invalid_srat; > > switch (sub_header->type) { > case ACPI_SRAT_TYPE_CPU_AFFINITY: > cpu = (struct acpi_srat_cpu_affinity *)sub_header; > + if (subtable_len < sizeof(*cpu)) > + goto invalid_srat; > + > pxm = *((u32 *)cpu->proximity_domain_hi) << 8 | > cpu->proximity_domain_lo; > if (pxm > max_pxm) > @@ -2084,6 +2090,9 @@ static void kfd_find_numa_node_in_srat(struct kfd_node > *kdev) > break; > case ACPI_SRAT_TYPE_GENERIC_AFFINITY: > gpu = (struct acpi_srat_generic_affinity *)sub_header; > + if (subtable_len < sizeof(*gpu)) > + goto invalid_srat; > + > bdf = *((u16 *)(&gpu->device_handle[0])) << 16 | > *((u16 *)(&gpu->device_handle[2])); > if (bdf == pci_id) { > @@ -2100,9 +2109,13 @@ static void kfd_find_numa_node_in_srat(struct kfd_node > *kdev) > > sub_header = (struct acpi_subtable_header *) > ((unsigned long)sub_header + subtable_len); > - subtable_len = sub_header->length; > } > > + goto out; > + > +invalid_srat: > + pr_err("SRAT contains an invalid subtable\n"); > +out: > acpi_put_table(table_header); > > /* Workaround bad cpu-gpu binding case */ > -- > 2.34.1 >
