A control region with no block windows may legally stop before the
window-size fields, so sizeof_dcr() first reads the windows count from
the shortened fixed portion. When the count is nonzero, however, the
helper returns sizeof(*dcr) without checking that the advertised
subtable contains the remaining fields.

add_dcr() then copies that full size. A malformed subtable that ends
immediately after a nonzero windows count can therefore make the copy
read beyond the control region.

Compute the required size from the windows count and require that size
to fit in the advertised subtable before returning it.

Fixes: b94d5230d06e ("libnvdimm, nfit: initial libnvdimm infrastructure and 
NFIT support")
Assisted-by: Codex:gpt-5
Signed-off-by: Pengpeng Hou <[email protected]>
---
 drivers/acpi/nfit/core.c | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/drivers/acpi/nfit/core.c b/drivers/acpi/nfit/core.c
index bf4ddc56494e..84c70f1941c5 100644
--- a/drivers/acpi/nfit/core.c
+++ b/drivers/acpi/nfit/core.c
@@ -817,12 +817,20 @@ EXPORT_SYMBOL_GPL(nfit_get_smbios_id);
  */
 static size_t sizeof_dcr(struct acpi_nfit_control_region *dcr)
 {
+       size_t size;
+
        if (dcr->header.length < offsetof(struct acpi_nfit_control_region,
                                window_size))
                return 0;
        if (dcr->windows)
-               return sizeof(*dcr);
-       return offsetof(struct acpi_nfit_control_region, window_size);
+               size = sizeof(*dcr);
+       else
+               size = offsetof(struct acpi_nfit_control_region, window_size);
+
+       if (size > dcr->header.length)
+               return 0;
+
+       return size;
 }
 
 static bool add_dcr(struct acpi_nfit_desc *acpi_desc,
-- 
2.50.1 (Apple Git-155)


Reply via email to