The character-device paths held the transaction and lifecycle lock while uiomove() accessed user memory. A user page fault could therefore delay suspend or detach, and a copyout failure occurred while the TPM response was still active. Copy commands into the bounded stack buffer before taking the lock. For reads, validate the response header, buffer the complete response while the lock is held, finish the TPM transaction, and copy it to userspace after unlocking. Use a non-blocking allocation so memory pressure cannot turn response buffering into another lifecycle wait. NetBSD uses the same separation but limits responses to its fixed 1 KiB buffer. Allocate the TPM-advertised response length to preserve the existing FreeBSD support for larger streamed responses. On a ThinkPad T440p with an STMicro TPM 1.2, a PCR read into a 4 KiB userspace buffer returned the expected 30-byte response. A deliberately short five-byte read failed cleanly, relinquished locality zero, and the next PCR read succeeded. MFC after: 2 weeks
Details
Details
Diff Detail
Diff Detail
- Repository
- rG FreeBSD src repository
- Lint
Lint Not Applicable - Unit
Tests Not Applicable
Event Timeline
| sys/dev/tpm/tpm.c | ||
|---|---|---|
| 1567 | I believe we want to restore uio_resid in the error paths after this to avoid inadvertently reporting a short write. I think the only short write that's valid here is one that successfully makes it all the way through sc_end(). | |
Comment Actions
The inline comment isn't really all that critical because the types of errors retuned today would be interpreted as fatal, so maybe it isn't worth it
Comment Actions
It's a good catch, The TPM wait paths can return errnos, which the write converts into a succcessful short write once uio_resid has chaged. I restored the original residual when a post-copy TPM op fails, and preserve the short count only after sc_end() succeeds.