@samitouri / QOSamiQemu / commits / c6d77ba44a

tpm_emulator: Reject a buffer size different than what was requested

When the TIS, SPAPR, or CRB frontends negotiate a buffer size with the TPM backend, then the tpm_emulator (swtpm) could still adjust this size of the buffer to within bounds supported by swtpm+libtpms if the chosen size was outside the acceptable range. This could theoretically lead to the TPM 2 using a bigger buffer than what was requested and memory allocated for. In practice this would not happend since the requested size of 4096 bytes for TIS and SPAPR and 3968 bytes for CRB happen in the (currently) supported range of ~2.5kb to 4096 bytes. With PQC support the range will have an upper bound of 8kb and a lower bound that will support the (pre-PQC) CRB with 3968 bytes. Fixes: 9375c44fdfc0 ("tpm: tpm_emulator: get and set buffer size of device") Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com> Link: https://lore.kernel.org/qemu-devel/20260511142219.797048-2-stefanb@linux.ibm.com Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>

Stefan Berger committed May 11, 2026 at 14:22 UTC c6d77ba44aebb5cbb9f20e75d890134947a785df
1 file changed +12 -1
backends/tpm/tpm_emulator.c
+12 -1
@@ -364,6 +364,7 @@ static int tpm_emulator_set_buffer_size(TPMBackend *tb,
364 {
365 TPMEmulator *tpm_emu = TPM_EMULATOR(tb);
366 ptm_setbuffersize psbs;
367 + size_t tpm_buffersize;
368
369 if (tpm_emulator_stop_tpm(tb, errp) < 0) {
370 return -1;
@@ -387,8 +388,18 @@ static int tpm_emulator_set_buffer_size(TPMBackend *tb,
388 return -1;
389 }
390
391 + tpm_buffersize = be32_to_cpu(psbs.u.resp.buffersize);
392 + /* Reject different buffer size used by the TPM than what was requested. */
393 + if (wanted_size != 0 && wanted_size != tpm_buffersize) {
394 + error_setg(errp,
395 + "tpm-emulator: TPM did not accept the requested buffer size "
396 + "of %zu bytes but adjusted it to %zu bytes",
397 + wanted_size, tpm_buffersize);
398 + return -1;
399 + }
400 +
401 if (actual_size) {
391 - *actual_size = be32_to_cpu(psbs.u.resp.buffersize);
402 + *actual_size = tpm_buffersize;
403 }
404
405 trace_tpm_emulator_set_buffer_size(