DF-4376 / verdict.json
{ "finding_id": "DF-4376", "status": "inconclusive", "reproduced": 0, "impact": "none", "confidence": "certain", "verdict": "Defect static-certain: dce112_create_resource_pool (dce112_resource.c:1343-1358) returns NULL on construct() failure without kfree(pool); constructs res_create_fail arm (1338-1341) runs destruct(pool) (697-767) which frees only the sub-objects, never the shell, so every failed amdgpu bind on a DCE112/Polaris ASIC leaks sizeof(struct dce110_resource_pool) (~1.5KB). Twin of accepted DF-4318 (dce80/81/83) and DF-4353 (dce110); the same leak exists in upstream Linux today. Runtime reproduction impossible on the verification guest: AMD_PCI_COUNT=0 (env.txt), amdgpu never binds, and no unprivileged trigger path exists (driver bind is privileged) \u2014 hence inconclusive rather than not_reproduced, mirroring the twins classification.", "exploit_chain": "", "evidence": "VERDICT.md (static trace with all construct() failure arms listed: clock sources 1168-1211, dccg/dmcu/abm/irqs 1213-1256, per-pipe loop 1258-1303, aux/i2c loop 1305-1321, resource_construct 1323-1325); env.txt (guest uname 6.5-DEVELOPMENT, full pciconf -l with zero 0x1002 devices, amdgpu KLD buildable in tree but unattachable); fix.diff git-apply-clean", "kernel_refs": [ "sys/dev/drm/amd/display/dc/dce112/dce112_resource.c:1343", "sys/dev/drm/amd/display/dc/dce112/dce112_resource.c:1353", "sys/dev/drm/amd/display/dc/dce112/dce112_resource.c:1357", "sys/dev/drm/amd/display/dc/dce112/dce112_resource.c:1338", "sys/dev/drm/amd/display/dc/dce112/dce112_resource.c:697" ], "poc_changes": "n/a (no seed; no runnable trigger exists without AMD hardware \u2014 pack documents the static proof and the environment probe)", "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": 5, "guest_dirty": 0, "build_cmd": "n/a (env probe: pciconf -l | grep -c 0x1002)", "run_cmd": "n/a (see run.sh note and VERDICT.md)", "code_hash": "", "notes": "Attempt 1: guest hardware probe \u2014 AMD_PCI_COUNT=0, path unreachable at runtime. Static proof is complete: no kfree of the shell on any failure path; destruct() only frees members. Bucket base:dev, severity Low (privileged rebind + memory pressure to accrue). Twin classifications: DF-4318 untested/not_testable, DF-4353 untested/not_testable \u2014 this pack uses inconclusive with the static-certainty narrative.", "recommended_fix": "Add kfree(pool) to the failure arm of dce112_create_resource_pool (see fix.diff) \u2014 destruct(pool) already ran inside construct(), so the shell free completes the cleanup", "fix_status": "not_testable", "fix_baseline_reproduced": 0, "fix_patched_reproduced": 0, "fix_verdict": "not_applicable->not_testable: no DCE112 hardware on the verification guest for a baseline or patched run. fix.diff (one added kfree(pool)) is git-apply-clean against sys/ (git apply --check OK); double-free impossible because constructs failure arm runs destruct(pool) exactly once and destruct never frees the shell nor is reachable again; identical fix shape as twin DF-4318/DF-4353 packs.", "fix_evidence": "git apply --check findings/poc/DF-4376/fix.diff => OK; sys/ left unmodified (git status --porcelain sys/ empty)" } |