From f0602ce389ccda0e8df35ccaec3c1024478a0b10 Mon Sep 17 00:00:00 2001 From: Stefan Berger Date: Mon, 11 May 2026 14:22:18 +0000 Subject: [PATCH] tpm_emulator: Disconnect if response exceeds negotiated buffer size MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Disconnect from the emulator if a response was to exceed the negotiated buffer size. The TPM TIS and SPAPR use 4096 bytes and the CRB 3968 bytes. There are currently no TPM 2 responses using this size of a buffer and therefore no response will be sent that is exceeding this size. Fixes: f4ede81eed29 ("tpm: Added support for TPM emulator") Reviewed-by: Marc-André Lureau Link: https://lore.kernel.org/qemu-devel/20260511142219.797048-3-stefanb@linux.ibm.com Signed-off-by: Stefan Berger --- backends/tpm/tpm_emulator.c | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/backends/tpm/tpm_emulator.c b/backends/tpm/tpm_emulator.c index ac5427b84e..95d2de2f48 100644 --- a/backends/tpm/tpm_emulator.c +++ b/backends/tpm/tpm_emulator.c @@ -176,8 +176,10 @@ static int tpm_emulator_unix_tx_bufs(TPMEmulator *tpm_emu, bool *selftest_done, Error **errp) { - ssize_t ret; bool is_selftest = false; + Error *local_err = NULL; + uint32_t to_read; + ssize_t ret; if (selftest_done) { *selftest_done = false; @@ -195,9 +197,25 @@ static int tpm_emulator_unix_tx_bufs(TPMEmulator *tpm_emu, return -1; } + /* + * Size of response from emulator must be <= out_len (= negotiated buffer + * size) + */ + to_read = tpm_cmd_get_size(out); + if (to_read > out_len) { + if (qio_channel_shutdown(tpm_emu->data_ioc, QIO_CHANNEL_SHUTDOWN_BOTH, + &local_err) < 0) { + error_report_err(local_err); + } + error_setg(errp, "tpm-emulator: Disconnected after receiving " + "unacceptable large response (%u > %u)", + to_read, out_len); + return -1; + } + ret = qio_channel_read_all(tpm_emu->data_ioc, (char *)out + sizeof(struct tpm_resp_hdr), - tpm_cmd_get_size(out) - sizeof(struct tpm_resp_hdr), errp); + to_read - sizeof(struct tpm_resp_hdr), errp); if (ret != 0) { return -1; }