git: 376fd49ae3b9 - stable/13 - APEI: Make sure event data fit into the buffer.

From: Alexander Motin <mav_at_FreeBSD.org>
Date: Sun, 13 Feb 2022 18:27:01 UTC
The branch stable/13 has been updated by mav:

URL: https://cgit.FreeBSD.org/src/commit/?id=376fd49ae3b9f07e122a3479f65c9414b38d7bae

commit 376fd49ae3b9f07e122a3479f65c9414b38d7bae
Author:     Alexander Motin <mav@FreeBSD.org>
AuthorDate: 2022-02-03 20:18:31 +0000
Commit:     Alexander Motin <mav@FreeBSD.org>
CommitDate: 2022-02-13 18:26:55 +0000

    APEI: Make sure event data fit into the buffer.
    
    There seem to be systems returning some garbage here.  I still don't
    know why, but at least I hope this check fix indefinite printf loop.
    
    MFC after:      2 weeks
    
    (cherry picked from commit 3b248a2113829e43c382f5e2b1f85c626c01f024)
---
 sys/dev/acpica/acpi_apei.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/sys/dev/acpica/acpi_apei.c b/sys/dev/acpica/acpi_apei.c
index c957959317ce..35bab30a68f1 100644
--- a/sys/dev/acpica/acpi_apei.c
+++ b/sys/dev/acpica/acpi_apei.c
@@ -371,8 +371,9 @@ apei_ge_handler(struct apei_ge *ge, bool copy)
 	uint8_t *buf = copy ? ge->copybuf : ge->buf;
 	ACPI_HEST_GENERIC_STATUS *ges = (ACPI_HEST_GENERIC_STATUS *)buf;
 	ACPI_HEST_GENERIC_DATA *ged;
+	size_t off, len;
 	uint32_t sev;
-	int i, c, off;
+	int i, c;
 
 	if (ges == NULL || ges->BlockStatus == 0)
 		return (0);
@@ -381,8 +382,11 @@ apei_ge_handler(struct apei_ge *ge, bool copy)
 	sev = ges->ErrorSeverity;
 
 	/* Process error entries. */
-	for (off = i = 0; i < c && off + sizeof(*ged) <= ges->DataLength; i++) {
+	len = MIN(ge->v1.ErrorBlockLength - sizeof(*ges), ges->DataLength);
+	for (off = i = 0; i < c && off + sizeof(*ged) <= len; i++) {
 		ged = (ACPI_HEST_GENERIC_DATA *)&buf[sizeof(*ges) + off];
+		if ((uint64_t)GED_SIZE(ged) + ged->ErrorDataLength > len - off)
+			break;
 		apei_ged_handler(ged);
 		off += GED_SIZE(ged) + ged->ErrorDataLength;
 	}