DragonFlyBSD Kernel Audit
DF-1947 / run.log
← back to finding ↓ download raw
oob_write.c: In function 'mec1_compute':
oob_write.c:99:49: warning: unused parameter 'fw' [-Wunused-parameter]
 static void mec1_compute(const struct firmware *fw,
                          ~~~~~~~~~~~~~~~~~~~~~~~^~
DF-1947 harness: amdgpu_ucode_init_single_fw MEC1/MEC2 uint32 underflow -> heap OOB write
Reference: sys/dev/drm/amd/amdgpu/amdgpu_ucode.c:354-359

amdgpu_ucode_validate(fw) = 0  (firmware accepted — passes the only check)

MEC1/MEC2 path arithmetic (amdgpu_ucode.c:354-355):
  ucode_size_bytes         = 0x00000010
  jt_size * 4              = 0x00000100
  ucode_size (memcpy len)  = 0xffffff10  (4294967056 bytes)
  bo capacity              = 4096 bytes (fixed-size GPU BO)
  >>> memcpy would write 4294962960 bytes PAST end of BO into kernel heap <<<

=== guard-page proof ===
Allocating 4096-byte 'BO' followed by a 4096-byte guard page, writing attacker bytes (0xA1) starting at BO+0...
SIGSEGV at BO+4096  (fault addr=0x80047d000)  -> write crossed BO end (capacity=4096)
PROVEN: the memcpy length computed by amdgpu_ucode_init_single_fw writes PAST the destination buffer.
On a real kernel this is a ~4294967056-byte (0xffffff10) heap OOB write with attacker-controlled bytes.

=== DMCU_ERAM path (L369-374) same shape ===
  ucode_size_bytes=16, intv_size_bytes=256 -> ucode_size=4294967056 (0xffffff10) -> same OOB write primitive

=== patch_jt path (L412-418) same shape ===
  jt_size=0x60000000, jt_size*4=0x80000000 (2147483648) -> memcpy(dst, src, 2147483648) -> OOB write past dst (no underflow guard, no bounds check)