DF-2407 / verdict.json
{ "status": "reproduced", "reproduced": 1, "impact": "panic", "confidence": "certain", "verdict": "The len==0 signed/unsigned promotion in tpm_tis12_write walks *p unbounded past the 1024-byte buffer, proven three ways with production code: (1) capture cap=1024 consumes exactly 1024 bytes and the last byte is the 0xC3 buffer fill; (2) cap=1536 consumes 1536 bytes and the last byte is 0x00 kernel-stack residue past the buffer, delivered to the TPM DATA register (the vTPM exfil channel); (3) walk mode keeps TPM_STS_DATA_EXPECT asserted and the production loop reads sequentially until it hits the kernel stack guard page: panic vm_fault fault on stack guard inside tpm_tis12_write. Full production dev path also verified: write(fd, buf, 0) on a tpm_ops cdev dispatches production tpmwrite -> sc_start -> tpm_tis12_write(buf,0), consumed 1536 bytes, returned EIO, guest alive.", "exploit_chain": "write(fd, buf, 0) on /dev/tpm (0600 root) -> tpmwrite -> tpm_tis12_write: OOB kernel-stack read streamed to the TPM DATA register; with a vTPM the bytes leave the guest (host-controlled info leak); with a physical TPM missing DATA_EXPECT the walk runs to the stack guard page and panics the kernel", "evidence": "run.log (capture pair + full-path), panic.txt (stack-guard fault trace)", "kernel_refs": [ "sys/dev/crypto/tpm/tpm.c:807", "sys/dev/crypto/tpm/tpm.c:821", "sys/dev/crypto/tpm/tpm.c:823", "sys/dev/crypto/tpm/tpm.c:1181" ], "poc_changes": "fabricated TIS register file + watchpoint-driven DATA_EXPECT drop; production tpm_tis12_write/tpmwrite from the stock tpm.ko module", "attempts": 5, "runtime_sec": 1200, "guest_dirty": 0, "build_cmd": "see build.sh (dfhw.ko + tpm.ko)", "run_cmd": "sysctl \"kern.dfhwgo=tis 1536\"; sysctl \"kern.dfhwgo=tis 0 walk\"; /root/tpm0 /dev/dfhtis0", "notes": "reachability: write(2) with count 0 is a legal call any root process can issue to a character device", "recommended_fix": "in tpmwrite reject n==0 before dispatch, and in tpm_tis12_write use size_t len so len-1 cannot become SIZE_MAX (guard cnt < (size_t)len)", "finding_id": "DF-2407", "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", "runner": "df-bsd-reviewer", "code_hash": "bf5e33eb3e71da639a8c9cff9bd4b362295143351973097e49b2cc06a11edfd8" } |