DF-5091 / verdict.json
{ "finding_id": "DF-5091", "status": "not_reproduced", "reproduced": false, "impact": "none", "confidence": "certain", "verdict": "Structural teardown gap confirmed in source and by runtime demonstration, but the UAF half is not reachable on any current configuration, so the security impact today is none. acpi_button_attach() installs AcpiInstallFixedEventHandler/AcpiInstallNotifyHandler with context=sc (acpi_button.c:150-151,158-159) and the driver has no device_detach (acpi_button.c:74-83), mirroring DF-5006 (acpi_cpu) and DF-5074 (acpi_acad). On the guest: the acpi_button driver is registered in the builtin kernel (kldstat -v), no acpi_button device instance is attached (dmesg empty; QEMU fixed buttons are handled by acpi.c:1974-1993), no acpi.ko exists to unload (kldunload acpi -> cant find file), and in a module build unloading acpi.ko aborts at bus_generic_detach (acpi.c:182) -> missing child detach -> ENXIO before any softc is freed. Net effect today: permanently pinned handlers/resources and a guaranteed UAF if a detach path is ever added (including via the AcpiOsExecute deferrals at acpi_button.c:255,258). Low severity, fix is cheap and belongs in-tree.", "exploit_chain": "", "evidence": "run.log (decisive: kldstat -v shows acpi/acpi_button driver registered; dmesg|grep acpi_button empty; kldunload acpi fails cant find file acpi; guest stays up). VERDICT.md for the full path:line trace; fix.diff for the proposed detach (git apply --check clean, not applied).", "kernel_refs": [ "sys/dev/acpica/acpi_button.c:74", "sys/dev/acpica/acpi_button.c:148", "sys/dev/acpica/acpi_button.c:150", "sys/dev/acpica/acpi_button.c:158", "sys/dev/acpica/acpi_button.c:169", "sys/dev/acpica/acpi_button.c:255", "sys/dev/acpica/acpi_button.c:266", "sys/dev/acpica/acpi.c:182", "sys/dev/acpica/acpi.c:1974", "sys/dev/acpica/Makefile:66" ], "poc_changes": "None \u2014 structural finding; trigger is a plain /bin/sh runtime demonstration (driver registration, device absence, blocked/absent unload path), no seed code to repair.", "attempts": 1, "guest_uname": "DragonFly dfbsd 6.5-DEVELOPMENT DragonFly 6.5-DEVELOPMENT #0: Thu Jul 2 06:02:54 UTC 2026 root@dfbsd:/usr/obj/usr/src/sys/X86_64_GENERIC x86_64", "runtime_sec": 45, "guest_dirty": 0, "build_cmd": "none (structural kernel-source finding; ./build.sh only syntax-checks trigger.sh)", "run_cmd": "findings/poc/DF-5091/run.sh (vm.sh run_root runs trigger.sh as root on the guest)", "code_hash": "52dbb2464f01a851a169ed5b8df3501b6d87f9ca7b3e29e22797fb2eff2e5b3d", "notes": "Guest left up and clean (all probes read-only; kldunload attempts failed benignly; no panic). Family: DF-5006 (acpi_cpu), DF-5074 (acpi_acad) \u2014 this is the acpi_button instance; includes the fixed-event-handler variant those lacked. acpi_lid.c (PNP0C0D) has the same gap and is filed separately by its own audit. Button sysctls hw.acpi.*_button_state belong to acpi.c, not this driver.", "recommended_fix": "Add acpi_button_detach() mirroring attach (remove fixed-event or notify handler; disable the PRW wake GPE) and register DEVMETHOD(device_detach, ...) \u2014 see fix.diff.", "fix_status": "not_testable", "fix_baseline_reproduced": 0, "fix_patched_reproduced": 0, "fix_verdict": "fix.diff authored and git-apply --check clean against sys/ but not build-validated: the finding produced no runtime fault on the baseline guest (structurally non-UAF today; no acpi_button device, no unload path), so there is no bad behavior to A/B. Fix validation is mandatory only when a memory-corruption finding reproduces.", "fix_evidence": "findings/poc/DF-5091/fix.diff (proposed, unapplied; adds acpi_button_detach + DEVMETHOD entry; notes the AcpiOsExecute drain requirement)" } |