Skip to content

fix(tpm2): bound allocations and loops driven by TPM responses - #1481

Merged
kvinwang merged 2 commits into
nextfrom
fix/tpm-count-alloc
Oct 23, 2026
Merged

kvinwang merged 2 commits into
nextfrom
fix/tpm-count-alloc

Conversation

@kvinwang

@kvinwang kvinwang commented Oct 23, 2026 •

Copy link
Copy Markdown
Collaborator

Problem

Follow-up to #1477; same input (a host-controlled vTPM), same impact (the guest aborts or stalls during boot):

  • TpmlPcrSelection and TpmlDigest unmarshal call Vec::with_capacity(count) with the TPM-supplied u32 count, and add_command_capability does the same with count + 1. count = 0xFFFFFFFF in a 4-byte buffer asks for ~100 GB before the first element fails to parse; the pcr_read paths reach this in the guest.
  • get_random loops until it has num_bytes; a TPM that keeps answering with an empty TPM2B makes it spin forever.
  • get_handles resumes at last_seen + 1; a TPM that answers more_data with a handle below the requested property sends it back to the same range forever.
  • nv_read does not truncate to the NV index's data_size (its sibling nv_read_with_auth does), so oversized chunks are returned as-is.

Fix

  • Cap the preallocation at what the remaining buffer could hold (count.min(buf.remaining()), / 4 for u32 attributes). Every entry consumes bytes, so a larger count fails with the existing underflow error.
  • get_random bails on an empty response.
  • get_handles bails when the TPM's last handle is below the requested start.
  • nv_read truncates to data_size, as nv_read_with_auth already does.

Verification

New test a_huge_list_count_fails_without_preallocating, run under ulimit -v 4000000:

  • with the fix: passes;
  • with the old with_capacity(count): memory allocation of 103079215080 bytes failed, process aborts.

New test get_handles_stops_when_the_tpm_goes_backwards (stream-backed fake TPM answering more_data with a handle below the range): the fixed code errors after 1 request; without the check it keeps asking and only stops when the fake TPM hangs up after 4.

cargo test -p tpm2 passes; cargo clippy -p tpm2 -- -D warnings -D clippy::unwrap_used -D clippy::expect_used clean.

@kvinwang
kvinwang force-pushed the fix/tpm-count-alloc branch from fced1c4 to 1205352 Compare October 23, 2026 05:19
Signed-off-by: Kevin Wang <wy721@qq.com>
…nv_read

Signed-off-by: Kevin Wang <wy721@qq.com>
@kvinwang
kvinwang force-pushed the fix/tpm-count-alloc branch from 1205352 to 143fe9b Compare October 23, 2026 05:27
@kvinwang
kvinwang merged commit 20ad2e6 into next Oct 23, 2026
12 checks passed
@kvinwang
kvinwang deleted the fix/tpm-count-alloc branch October 23, 2026 05:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant