[PATCH] tpm_emulator: Limit number of bytes read from buffer to size of buffer

Stefan Berger posted 1 patch 1 month ago
Patches applied successfully (tree, apply log)
git fetch https://github.com/patchew-project/qemu tags/patchew/20260429193007.1670335-1-stefanb@linux.ibm.com
Maintainers: Stefan Berger <stefanb@linux.vnet.ibm.com>
backends/tpm/tpm_emulator.c | 23 ++++++++++++++++++++---
1 file changed, 20 insertions(+), 3 deletions(-)
[PATCH] tpm_emulator: Limit number of bytes read from buffer to size of buffer
Posted by Stefan Berger 1 month ago
Limit the number of bytes read from the TPM response to the size of the
receiving buffer and drain the other bytes from the response by reading
them into a temporary buffer.

The size of the TPM's responses should fit into a buffer negotiated with
the tpm_emulator (swtpm). However, it is better to proactively limit the
number of bytes read into the buffer by using the buffer's size as an
upper limit.

Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
---
 backends/tpm/tpm_emulator.c | 23 ++++++++++++++++++++---
 1 file changed, 20 insertions(+), 3 deletions(-)

diff --git a/backends/tpm/tpm_emulator.c b/backends/tpm/tpm_emulator.c
index 75c33d290e..5e8bad1632 100644
--- a/backends/tpm/tpm_emulator.c
+++ b/backends/tpm/tpm_emulator.c
@@ -176,8 +176,11 @@ static int tpm_emulator_unix_tx_bufs(TPMEmulator *tpm_emu,
                                      bool *selftest_done,
                                      Error **errp)
 {
-    ssize_t ret;
     bool is_selftest = false;
+    uint8_t buffer[1024];
+    size_t to_drain = 0;
+    size_t to_read;
+    ssize_t ret;
 
     if (selftest_done) {
         *selftest_done = false;
@@ -195,13 +198,27 @@ static int tpm_emulator_unix_tx_bufs(TPMEmulator *tpm_emu,
         return -1;
     }
 
+    to_read = tpm_cmd_get_size(out) - sizeof(struct tpm_resp_hdr);
+    if (to_read > out_len) {
+        to_drain = to_read - out_len;
+        to_read = out_len;
+    }
+
     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);
+              (char *)out + sizeof(struct tpm_resp_hdr), to_read, errp);
     if (ret != 0) {
         return -1;
     }
 
+    while (to_drain) {
+        to_read = MIN(to_drain, sizeof(buffer));
+        ret = qio_channel_read_all(tpm_emu->data_ioc, buffer, to_read, errp);
+        if (ret != 0) {
+            return -1;
+        }
+        to_drain -= to_read;
+    }
+
     if (is_selftest) {
         *selftest_done = tpm_cmd_get_errcode(out) == 0;
     }
-- 
2.43.0