{
  "finding_id": "DF-2386",
  "status": "reproduced",
  "reproduced": 1,
  "impact": "panic",
  "confidence": "certain",
  "verdict": "Confirmed deterministically on the verbatim driver compiled byte-identical into a custom INVARIANTS kernel: acpi_panasonic_sinf discards the AcpiEvaluateObject status (acpi_panasonic.c:277) and dereferences res = buf.Pointer (set NULL by the driver itself at :276 and left NULL by every ACPICA failure path, nsxfeval.c:525-631) at :279 -- an unprivileged local user reading the CTLFLAG_ANYBODY sysctl hw.acpi.panasonic.lcd_brightness while the SINF evaluation fails panics the kernel: full trap block captured (fatal trap 12, fault va 0x0, Stopped at acpi_panasonic_sinf+0x5d cmpl 0x4,(%rdi) -- the ACPI_TYPE_PACKAGE comparison on NULL, attributed by the kernel to the sysctl process). Reach requires Panasonic MAT0019 firmware plus an SINF evaluation failure at read time (AE_NO_MEMORY under memory pressure or a firmware anomaly) -- the rig injects exactly that failure at the exact ACPICA boundary the driver consumes. Impact is a reliable NULL-deref panic / local DoS from an unprivileged read; no write primitive, not a privesc. fix.diff (status check + NULL/type/Count guards + guarded free) A/B validated: same trigger returns -1 with no panic. The first fix iteration was itself caught by the rig (it reached AcpiOsFree(NULL) and panicked via kern_slaballoc.c:1407 on INVARIANTS) and was amended to guard the free -- the idiom the driver itself uses at :420-421.",
  "exploit_chain": "uid 1001 maxx -> sysctl read of hw.acpi.panasonic.lcd_brightness (CTLFLAG_ANYBODY, acpi_panasonic.c:171) -> acpi_panasonic_sysctl -> ACPI_SERIAL_BEGIN -> hkey_lcd_brightness(HKEY_GET) -> acpi_panasonic_sinf(reg 0x04) -> AcpiEvaluateObject fails AE_NO_MEMORY leaving buf.Pointer NULL -> res->Type load from NULL -> fatal trap 12, kernel panic, system halt. Chain ceiling is DoS: the faulting access is a 4-byte read at address 0x0 with no attacker-controlled write, so no uid0 escalation exists for this class.",
  "evidence": "panic.txt (full trap block: fatal trap 12, fault virtual address 0x0, current process = the unprivileged sysctl, Stopped at acpi_panasonic_sinf+0x5d cmpl 0x4,(%rdi)); run.log (control read = 128 by maxx, then armed trigger); run_fixed.log (trigger returns -1, RC=0, guest alive); serial.txt; panasim.c/panasim.h/pana_shim.c (rig); build.log (nativekernel build); env.txt",
  "kernel_refs": [
    "sys/dev/acpica/acpi_panasonic/acpi_panasonic.c:275-276",
    "sys/dev/acpica/acpi_panasonic/acpi_panasonic.c:277",
    "sys/dev/acpica/acpi_panasonic/acpi_panasonic.c:278-280",
    "sys/dev/acpica/acpi_panasonic/acpi_panasonic.c:171",
    "sys/dev/acpica/acpi_panasonic/acpi_panasonic.c:248-254",
    "sys/contrib/dev/acpica/source/components/namespace/nsxfeval.c:530-566",
    "sys/contrib/dev/acpica/source/components/namespace/nsxfeval.c:541-545",
    "sys/contrib/dev/acpica/source/components/namespace/nsxfeval.c:580",
    "sys/kern/kern_slaballoc.c:1407"
  ],
  "poc_changes": "No seed PoC existed. Built the verbatim-interposition kernel harness from scratch (same protocol as the acpi_hp rig DF-2383): pana_shim.c build glue renames the driver ACPI externals at the preprocessor level and includes the sha256-gated verbatim source; panasim.c fabricates the firmware world (SINF/HINF/SSET replies honoring the ACPICA failure contract, notify-handler capture, fake newbus child on the real acpi0 so the real sysctls appear under hw.acpi.panasonic). Iterations: (1) missing panasim.h prototypes tripped -Werror; (2) blanket-matching fake ACPI_ID_PROBE let the driver hijack an unrelated unit-0 ACPI child at boot -- fixed to match only the rig-created device; (3) first fix.diff iteration panicked in AcpiOsFree(NULL) on INVARIANTS -- amended with a NULL guard before the free.",
  "attempts": 4,
  "guest_uname": "DragonFly dfbsd 6.5-DEVELOPMENT DragonFly 6.5-DEVELOPMENT #4: Mon Oct 19 09:05:52 UTC 2026     root@dfbsd:/usr/obj/usr/src/sys/PANHARNESS  x86_64",
  "runtime_sec": 8400,
  "guest_dirty": 0,
  "build_cmd": "sh build.sh          # sha256-gated verbatim acpi_panasonic.c + rig -> make -j6 nativekernel KERNCONF=PANHARNESS -> installkernel -> reboot;  sh build.sh fixed   # applies fix.diff to the guest tree copy and rebuilds",
  "run_cmd": "sh run.sh baseline    # create device, maxx control read (sane SINF), arm hw.panasim.sinf_mode=0 (evaluation fails), maxx re-reads -> panic;  sh run.sh fixed     # same sequence -> -1, no panic",
  "code_hash": "a70387113f982a4e39cc0daf840d67df623a06cdbcd64a5b48c1ab3aafd39ac7",
  "notes": "Guest has no Panasonic hardware; the rig supplies the firmware side at the exact API boundary the findings describe -- that boundary (what AcpiEvaluateObject returns on failure) is the trust boundary under test and was verified against the ACPICA source contract. DF-2589 duplicates the sinf half of this finding and DF-2590 is the same class in the notify path (per the pass-2 negative-evidence note for this file). Console note: output from the injected-notify kthread is dropped by the console layer (both kprintf and the trap block); the DF-2386 sysctl-context panic prints fully.",
  "recommended_fix": "acpi_panasonic_sinf: check AcpiEvaluateObject status, verify res != NULL and res->Type == ACPI_TYPE_PACKAGE and index < res->Package.Count before reading Elements[index], and free buf.Pointer only when non-NULL"
}
