⬢ DragonFlyBSD Kernel Audit
DF-2409 / panic.txt
← back to finding ↓ download raw
Fatal trap 9: general protection fault while in kernel mode
Stopped at      tpm20_discard_buffer+0x3d:      movq    $0,(%rcx)

Sequence (production code, /dev/tpm0 made by production tpm20_init):
  sysctl kern.dfhwgo=t20_setup      -> tpm20_init() -> /dev/tpm0 (0600)
  open("/dev/tpm0"), write(fd, 32 bytes), close()
       -> production tpm20_write: transmit ok -> callout_reset(
          &sc->discard_buffer_callout, 500ms, tpm20_discard_buffer, sc)
  sysctl t20_snapshot               -> rig saves sc bytes
  sysctl t20_release_canary         -> PRODUCTION tpm20_release(sc)
          (frees sc->buf, lockuninit, cv_destroy, destroy_dev; NEVER
          drains discard_buffer_callout) + kfree(sc) + immediate
          same-size kmalloc resurrect at the same address with the
          saved bytes and sc->buf = 0x4141414141414141
  ~500 ms after the write: the stale callout fires into the freed
  chunk -> tpm20_discard_buffer runs -> memset(sc->buf = canary) ->
  non-canonical store -> #GP at the memset instruction.

Root cause: tpm20.c:199-213 tpm20_release has no
callout_stop/callout_drain(&sc->discard_buffer_callout) (the harvest
callout IS drained under #ifdef TPM_HARVEST); tpm20_write arms it at
tpm20.c:144-146.