# DF-4353 VERDICT

**Status: untested (kernel path) — code defect certain; guest model
demonstrates the orphaned allocations and the fix accounting.**

## Root cause (line-accurate)
1. `dce110_create_resource_pool` (dce110_resource.c:1398-1414):
   ```
   1403: pool = kzalloc(sizeof(struct dce110_resource_pool));
   1409: if (construct(num_virtual_links, dc, pool, asic_id))
   1410:     return &pool->base;
   1412: BREAK_TO_DEBUGGER();
   1413: return NULL;                      <-- no kfree(pool)
   ```
   construct()'s `res_create_fail` arm (:1393-1395) runs `destruct(pool)`
   which frees only the sub-objects (opps/transforms/ipps/mis/tgs,
   engines/i2cs, stream encs, clock sources, audios, abm, dmcu, dccg,
   irqs — :703-773).  The pool allocation itself is orphaned; the caller
   (core/dc.c dc_construct → dce110_create_resource_pool) never received
   the pointer and can only destruct(dc).  This is the exact DF-4318
   error-path shape at the DCE11 (Carrizo/Stoney) instance; the pool
   embeds the full `struct resource_pool` base (core_types.h:120-198,
   incl. 12-pointer stream_enc[] and the engine arrays) — ~KB per failed
   pool build.  Failure triggers include any sub-object create failure
   (OOM), irq-service create failure (:1307-1310), resource_construct
   failure (:1378-1380), and a VBIOS reporting no external DP clock
   source (:1253-1257); rebind/hotplug loops amplify.

2. Sibling asymmetry (DF-4309 flavor): construct() also does
   `if (dc->config.fbc_support) dc->fbc_compressor =
   dce110_compressor_create(ctx);` (:1372-1373).  `grep -rn
   dce110_compressor_destroy` — the destroy function
   (dce110_compressor.c:439) has **zero callers** anywhere in the tree:
   the compressor is allocated on dc and never freed on any teardown
   path.

## Verification
- Kernel path untestable on the audit guest: no AMD GPU (pciconf as
  root shows i440FX/PIIX + virtio only; env.txt); amdgpu.ko present but
  unbindable.
- Guest model `df4353.c` (cc 8.3; build.log/run.log) reproduces the
  allocation accounting of the failure arm (DF-4318's methodology):
  baseline failure leaves `live_allocs=2` (pool + compressor) —
  "LEAK CONFIRMED (model)"; the fixed arm leaves 0 —
  "FIX MODEL CLEAN (model)".

## Fix validation
Kernel-level validation impossible on this guest.  fix.diff (git apply
--check clean) adds `kfree(pool)` after the existing
BREAK_TO_DEBUGGER in the failure arm (destruct already ran inside
construct — no double free) and destroys dc->fbc_compressor in
construct's res_create_fail arm.  Note: the *successful*-path lifecycle
gap (dc_destroy never freeing fbc_compressor) lives in core/dc.c and is
not reachable from this file; the local fix closes the error arm, the
model shows both allocations accounted.

## Fix status (batch validation)
Applied with the 36 sibling fix.diffs of this batch in findings/poc/_batch41/all_fixes.patch; single in-guest `make -j6 nativekernel KERNCONF=X86_64_GENERIC` completed RC=0 with zero errors under -Werror (full log: findings/poc/_batch41/fix_build8.log). Behavior A/B intentionally skipped for this Info-tier item.
