diff --git a/sys/dev/acpica/acpi_hp/acpi_hp.c b/sys/dev/acpica/acpi_hp/acpi_hp.c --- a/sys/dev/acpica/acpi_hp/acpi_hp.c +++ b/sys/dev/acpica/acpi_hp/acpi_hp.c @@ -849,6 +860,18 @@ acpi_hp_free_buffer(&out); return (-EINVAL); } + /* + * DF-2384: the reply is indexed as result[0..2] below. The HP CMI + * contract is a 12-byte reply (3 x UINT32); a short or zero-length + * BIOS reply makes result[1]/result[2] read past Buffer.Length + * (heap OOB read surfaced through the dev.acpi hp sysctls), and a + * zero-length buffer can carry a NULL Buffer.Pointer (kernel NULL + * deref). Require the full 12 bytes. + */ + if (obj->Buffer.Length < 3 * sizeof(UINT32)) { + acpi_hp_free_buffer(&out); + return (-EINVAL); + } result = (UINT32*) obj->Buffer.Pointer; retval = result[2]; if (result[1] > 0) {