diff --git a/sys/dev/drm/radeon/radeon_bios.c b/sys/dev/drm/radeon/radeon_bios.c --- a/sys/dev/drm/radeon/radeon_bios.c +++ b/sys/dev/drm/radeon/radeon_bios.c @@ -204,6 +204,17 @@ } obj = (ACPI_OBJECT *)buffer.Pointer; + + /* DF-1783: ACPI_OBJECT is a union; only trust Buffer.Length when + * the method actually returned a Buffer, and never copy more than + * the caller asked for. A malicious _ATRM (custom SSDT / option + * ROM) could return a non-Buffer type or an over-long Length and + * overflow the caller's bios buffer. */ + if (obj->Type != ACPI_TYPE_BUFFER || + obj->Buffer.Length > (ACPI_SIZE)len) { + AcpiOsFree(buffer.Pointer); + return -ENODEV; + } memcpy(bios+offset, obj->Buffer.Pointer, obj->Buffer.Length); len = obj->Buffer.Length; AcpiOsFree(buffer.Pointer);