git: a1e236e9d610 - main - acpi_spmc: Check AMD constraint packages

From: Aymeric Wibo <obiwac_at_FreeBSD.org>
Date: Sat, 12 Sep 2026 11:35:22 UTC
The branch main has been updated by obiwac:

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

commit a1e236e9d610be69c9fcde0162a09385a2feb49f
Author:     Aymeric Wibo <obiwac@FreeBSD.org>
AuthorDate: 2026-09-10 12:10:10 +0000
Commit:     Aymeric Wibo <obiwac@FreeBSD.org>
CommitDate: 2026-09-12 11:29:00 +0000

    acpi_spmc: Check AMD constraint packages
    
    Also match behaviour with Intel constraint parsing by skipping malformed
    constraints instead of failing hard.
    
    Reviewed by:    olce
    Sponsored by:   The FreeBSD Foundation
    Event:          EuroBSDCon Devsummit 2026
    Differential Revision:  https://reviews.freebsd.org/D59568
---
 sys/dev/acpica/acpi_spmc.c | 44 ++++++++++++++++++++++++++++++++++++++------
 1 file changed, 38 insertions(+), 6 deletions(-)

diff --git a/sys/dev/acpica/acpi_spmc.c b/sys/dev/acpica/acpi_spmc.c
index d91df4d56afc..32456852052c 100644
--- a/sys/dev/acpica/acpi_spmc.c
+++ b/sys/dev/acpica/acpi_spmc.c
@@ -724,6 +724,18 @@ acpi_spmc_parse_constraints_amd(struct acpi_spmc_softc *sc, ACPI_OBJECT *object)
 	struct acpi_spmc_constraint *constraint;
 	ACPI_OBJECT	*name_obj;
 
+	if (object->Type != ACPI_TYPE_PACKAGE) {
+		device_printf(sc->dev, "AMD: Constraints: object not "
+		    "package.\n");
+		return (ENXIO);
+	}
+	if (object->Package.Count != 3) {
+		device_printf(sc->dev,
+		    "AMD: Constraints: Package has %d elements\n",
+		    object->Package.Count);
+		return (ENXIO);
+	}
+
 	/*
 	 * First element in the package is unknown.
 	 * Second element is the number of device constraints.
@@ -732,6 +744,11 @@ acpi_spmc_parse_constraints_amd(struct acpi_spmc_softc *sc, ACPI_OBJECT *object)
 	constraint_count = object->Package.Elements[1].Integer.Value;
 	constraints = &object->Package.Elements[2];
 
+	if (constraints->Type != ACPI_TYPE_PACKAGE) {
+		device_printf(sc->dev,
+		    "AMD: Constraints: Third element not a package\n");
+		return (ENXIO);
+	}
 	if (constraints->Package.Count != constraint_count) {
 		device_printf(sc->dev,
 		    "AMD: Constraints: Count mismatch (%d to %zu)\n",
@@ -743,28 +760,43 @@ acpi_spmc_parse_constraints_amd(struct acpi_spmc_softc *sc, ACPI_OBJECT *object)
 	sc->constraints = malloc(constraint_count * sizeof *sc->constraints,
 	    M_TEMP, M_WAITOK | M_ZERO);
 
-	for (size_t i = 0; i < constraint_count; i++) {
+	for (size_t i = 0, j = 0; i < constraint_count; i++) {
 		/* Parse the constraint package. */
 		constraint_obj = &constraints->Package.Elements[i];
+		constraint = &sc->constraints[j];
+
+		if (constraint_obj->Type != ACPI_TYPE_PACKAGE) {
+			device_printf(sc->dev,
+			    "AMD: Constraint %zu not a package\n", i);
+			goto skip;
+		}
 		if (constraint_obj->Package.Count != 4) {
 			device_printf(sc->dev,
 			    "AMD: Constraint %zu has %d elements, not 4\n",
 			    i, constraint_obj->Package.Count);
-			acpi_spmc_free_constraints(sc);
-			return (ENXIO);
+			goto skip;
 		}
 
-		constraint = &sc->constraints[i];
 		constraint->enabled =
 		    constraint_obj->Package.Elements[0].Integer.Value;
-
 		name_obj = &constraint_obj->Package.Elements[1];
-		constraint->name = strdup(name_obj->String.Pointer, M_TEMP);
 
+		if (name_obj->Type != ACPI_TYPE_STRING) {
+			device_printf(sc->dev,
+			    "AMD: Constraint %zu's name is not string.\n", i);
+			goto skip;
+		}
+
+		constraint->name = strdup(name_obj->String.Pointer, M_TEMP);
 		constraint->function_states =
 		    constraint_obj->Package.Elements[2].Integer.Value;
 		constraint->min_d_state =
 		    constraint_obj->Package.Elements[3].Integer.Value;
+
+		j++;
+		continue;
+skip:
+		sc->constraint_count--;
 	}
 
 	return (0);