DragonFlyBSD Kernel Audit
DF-1989 / tpm_crb_oob.c
← back to finding ↓ download raw
/*
 * PoC: tpmcrb_attach / tpmcrb_transmit OOB MMIO via malicious CRB register
 *       values (DF-1989)
 *
 * There is no unprivileged-user "ioctl to crash" path that can be exercised
 * from inside a guest that has no TPM CRB device at all.  The realistic
 * trigger requires a CRB device to be presented to the guest (e.g. by a
 * malicious hypervisor or buggy swtpm).  The audit QEMU guest has no TPM
 * (no /dev/tpm*, no tpmcrb device in pciconf -l), so the bug is confirmed
 * by source-tracing only (see VERDICT.md).
 *
 * This file documents the trigger and the failed attempt to run it on the
 * audit guest.  The actual exploitation requires either:
 *
 *   1. A hypervisor that presents a CRB device with cmd_off/cmd_buf_size/
 *      rsp_off/rsp_buf_size values placing the buffer outside the MMIO BAR,
 *      then issuing any TPM command (root: dd 10 bytes to /dev/tpm0), or
 *      suspend/shutdown (which fires tpm20_save_state -> tpmcrb_transmit,
 *      reachable without /dev/tpm0 access).
 *
 *   2. (Out of scope here) booting a guest with `qemu ... -chardev
 *      socket,id=chr,path=/tmp/swtpm.sock -tpmdev emulator,id=tpm0,chardev=chr
 *      -device tpm-crb-device,tpmdev=tpm0` and a patched swtpm that returns
 *      bogus register values.
 *
 * On the audit QEMU guest we cannot reproduce at runtime; the absence is
 * verified by:
 *    pciconf -l | grep -i 'tpm\|crypto'   =>  no matches
 *    ls /dev/tpm*                          =>  No such file or directory
 */

#include <stdio.h>

int main(void) {
    printf("DF-1989 PoC: requires a TPM CRB device to be presented to the guest.\n");
    printf("This audit QEMU guest has no TPM (no /dev/tpm*, no tpmcrb in pciconf -l).\n");
    printf("Bug confirmed by source-trace; see VERDICT.md.\n");
    return 0;
}