git: 508efe35e577 - main - acpi_spmc: Check Intel constraint packages

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

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

commit 508efe35e577e322ab839def893f9ccb9826a9e4
Author:     Aymeric Wibo <obiwac@FreeBSD.org>
AuthorDate: 2026-09-10 09:40:35 +0000
Commit:     Aymeric Wibo <obiwac@FreeBSD.org>
CommitDate: 2026-09-12 11:28:59 +0000

    acpi_spmc: Check Intel constraint packages
    
    Some firmware inexplicably decides to do non-standard and annoying stuff
    here, e.g. the Fujitsu Futro S940 with an Intel Pentium J5005 sometimes
    returns the following when calling the DEVICE_CONSTRAINTS function on
    the Intel DSM:
    
        Return (Package (0x01)
        {
            Zero
        })
    
    (Package elements here are supposed to be constraint packages, not just a
    single value.)
    
    First reported in the following forum post:
    
    https://forum.netgate.com/topic/201090/2.9.0-beta-leads-to-kernel-panic-on-boot
    
    Reported by:    TampertK on forum.netgate.com
    Reviewed by:    olce
    Sponsored by:   The FreeBSD Foundation
    Event:          EuroBSDCon Devsummit 2026
    Differential Revision:  https://reviews.freebsd.org/D59566
---
 sys/dev/acpica/acpi_spmc.c | 50 +++++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 45 insertions(+), 5 deletions(-)

diff --git a/sys/dev/acpica/acpi_spmc.c b/sys/dev/acpica/acpi_spmc.c
index 8691354ff4d9..d91df4d56afc 100644
--- a/sys/dev/acpica/acpi_spmc.c
+++ b/sys/dev/acpica/acpi_spmc.c
@@ -636,13 +636,38 @@ acpi_spmc_parse_constraints_intel(struct acpi_spmc_softc *sc, ACPI_OBJECT *objec
 		constraint_obj = &object->Package.Elements[i];
 		constraint = &sc->constraints[j];
 
+		if (constraint_obj->Type != ACPI_TYPE_PACKAGE) {
+			device_printf(sc->dev, "Intel: Wrong element type for "
+			    "constraint %zu.\n", i);
+			goto skip;
+		}
+		if (constraint_obj->Package.Count != 3) {
+			device_printf(sc->dev, "Intel: Wrong package length "
+			    "for constraint %zu's package.\n", i);
+			goto skip;
+		}
+
+		name_obj = &constraint_obj->Package.Elements[0];
 		constraint->enabled =
 		    constraint_obj->Package.Elements[1].Integer.Value;
+		detail = &constraint_obj->Package.Elements[2];
 
-		name_obj = &constraint_obj->Package.Elements[0];
-		constraint->name = strdup(name_obj->String.Pointer, M_TEMP);
+		if (name_obj->Type != ACPI_TYPE_STRING) {
+			device_printf(sc->dev,
+			    "Intel: Constraint %zu's name is not string.\n", i);
+			goto skip;
+		}
+		if (detail->Type != ACPI_TYPE_PACKAGE) {
+			device_printf(sc->dev, "Intel: Wrong element type for "
+			    "constraint %zu's detail package.\n", i);
+			goto skip;
+		}
+		if (detail->Package.Count != 2) {
+			device_printf(sc->dev, "Intel: Wrong package length "
+			    "for constraint %zu's detail package.\n", i);
+			goto skip;
+		}
 
-		detail = &constraint_obj->Package.Elements[2];
 		/*
 		 * The first element in the device constraint detail package is
 		 * the revision, and should always be zero.
@@ -656,12 +681,24 @@ acpi_spmc_parse_constraints_intel(struct acpi_spmc_softc *sc, ACPI_OBJECT *objec
 				    "Intel: Unknown revision %d for "
 				    "constraint %zu's detail package\n",
 				    revision, i);
-			sc->constraint_count--;
-			continue;
+			goto skip;
 		}
 
 		constraint_package = &detail->Package.Elements[1];
 
+		if (constraint_package->Type != ACPI_TYPE_PACKAGE) {
+			device_printf(sc->dev, "Intel: Wrong element type for "
+			    "constraint %zu's constraint package.\n", i);
+			goto skip;
+		}
+		if (constraint_package->Package.Count != 3) {
+			device_printf(sc->dev, "Intel: Wrong package length "
+			    "for constraint %zu's constraint package.\n", i);
+			goto skip;
+		}
+
+		constraint->name = strdup(name_obj->String.Pointer, M_TEMP);
+
 		constraint->lpi_uid =
 		    constraint_package->Package.Elements[0].Integer.Value;
 		constraint->min_d_state =
@@ -670,6 +707,9 @@ acpi_spmc_parse_constraints_intel(struct acpi_spmc_softc *sc, ACPI_OBJECT *objec
 		    constraint_package->Package.Elements[2].Integer.Value;
 
 		j++;
+		continue;
+skip:
+		sc->constraint_count--;
 	}
 
 	return (0);