DF-2387 / verdict.json
{ "finding_id": "DF-2387", "status": "reproduced", "reproduced": 1, "impact": "leak", "confidence": "certain", "verdict": "Confirmed on the verbatim driver in the same kernel rig as DF-2386: acpi_panasonic_sinf reads res->Package.Elements[index] (acpi_panasonic.c:280) with fixed register indices 0x02..0x08 and never consults res->Package.Count. With a fabricated short SINF package (Count=2), the unprivileged reader of the CTLFLAG_ANYBODY sysctls received exactly the per-index canary planted past Count (reg2 -> 0xC2C2C2C2, reg3 -> 0xC3C3C3C3, reg4 -> 0xC4C4C4C4, reg8 -> 0xC8C8C8C8; the returned value identifies the exact out-of-package index read), and with a tight 72-byte package allocation plus same-zone grooming the reads crossed into the adjacent kernel heap chunk and returned the planted 0xEEEEEEEE marker content 5/5 runs -- a cross-chunk kernel heap read disclosed to an unprivileged user with no crash. Reach requires Panasonic MAT0019 firmware whose SINF method returns a short/malformed package (firmware defect or crafted ACPI table, exactly the finding precondition); on conformant firmware the read is in-bounds. Ceiling is a bounded one-UINT32-per-read kernel heap disclosure; no write primitive, not a privesc. fix.diff (index < Count guard) A/B validated: every short-package read returns -1 on the fixed kernel (15/15 across all modes), no panic.", "exploit_chain": "uid 1001 maxx -> sysctl read hw.acpi.panasonic.{lcd_brightness_max,lcd_brightness_min,lcd_brightness,sound_mute} (CTLFLAG_ANYBODY) -> acpi_panasonic_sinf(reg) -> Elements[reg].Integer.Value read without Count check -> UINT32 truncation -> sysctl_handle_int -> unprivileged userspace. Grooming demonstration is rig-side (kernel allocations adjacent to the package); an unprivileged user cannot directly shape the neighboring chunks, so the realistic ceiling is disclosure of incidental adjacent heap contents, matching Low severity.", "evidence": "canary_run.txt (reg2/3/4/8 returned 0xC2/C3/C4/C8C2.. canaries); spray_run.txt + leak_sample.txt (5/5 reads of 0xEEEEEEEE from the chunk behind the 72-byte package allocation); tight_run.txt (ungroomed zeros); run.log (sane control 255/0/128/0); run_fixed.log (all modes -> -1); panasim.c (SINF_CANARY/SINF_TIGHT/SINF_TIGHT_SPRAY modes)", "kernel_refs": [ "sys/dev/acpica/acpi_panasonic/acpi_panasonic.c:279-280", "sys/dev/acpica/acpi_panasonic/acpi_panasonic.c:316", "sys/dev/acpica/acpi_panasonic/acpi_panasonic.c:337", "sys/dev/acpica/acpi_panasonic/acpi_panasonic.c:363", "sys/dev/acpica/acpi_panasonic/acpi_panasonic.c:382", "sys/dev/acpica/acpi_panasonic/acpi_panasonic.c:254", "sys/dev/acpica/acpi_panasonic/acpi_panasonic.c:171" ], "poc_changes": "No seed PoC existed; reused the DF-2386 verbatim-interposition rig unchanged and added SINF reply modes: SINF_CANARY (Count=2 with per-index canary tail for attribution), SINF_TIGHT (Count=2 with a tight 3*sizeof(ACPI_OBJECT)=72-byte allocation) and SINF_TIGHT_SPRAY (same-size marked neighbors allocated directly behind the package -- the first spray attempt used 256-byte chunks, a different malloc zone than the 72-byte package, and returned zeros; measured sizeof(ACPI_OBJECT)=24 from the harness boot line and switched to exact same-size grooming).", "attempts": 3, "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": 1800, "guest_dirty": 0, "build_cmd": "sh build.sh # shared with DF-2386 (verbatim driver + rig, PANHARNESS kernel)", "run_cmd": "sh run.sh # sane control, canary attribution, tight x5, tight+spray x5 -- all reads as maxx (uid 1001)", "code_hash": "a70387113f982a4e39cc0daf840d67df623a06cdbcd64a5b48c1ab3aafd39ac7", "notes": "No panic in any mode (reads stay inside mapped slab memory) -- the disclosure is silent on the stock kernel. The canary values reaching userspace are the attribution artifact; on real short-firmware the values would be whatever ACPICA-adjacent heap contains. External ACPI_OBJECT is 24 bytes, so the 9-element package is only 240 bytes and index 8 reads at package+216 -- within the canary backing store, and 48+ bytes past the tight allocation.", "recommended_fix": "acpi_panasonic_sinf: only read Elements[index] after verifying res != NULL, res->Type == ACPI_TYPE_PACKAGE and index < res->Package.Count (part of the shared fix.diff with DF-2386)" } |