Avoid a potential integer underflow in tpm_crb_fill_command_response that could occur if s->response_offset > s->response_buffer->len and the function's call sites were to change.
tpm_crb_fill_command_response currently has 3 callers that either test that 's->response_offset < s->response_buffer->len' is true or ensure that s->response_offset = 0 and s->response_buffer->len >= 0. Therefore, the integer underflow cannot currently occur. In the worst case the subtraction would lead to a '0'. Signed-off-by: Stefan Berger <[email protected]> --- hw/tpm/tpm_crb.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/hw/tpm/tpm_crb.c b/hw/tpm/tpm_crb.c index e5e33a3a2f..9a9677db6b 100644 --- a/hw/tpm/tpm_crb.c +++ b/hw/tpm/tpm_crb.c @@ -180,10 +180,17 @@ static void tpm_crb_fill_command_response(CRBState *s) * to the linux guest in chunks by writing it back to MMIO region. */ void *mem = memory_region_get_ram_ptr(&s->cmdmem); - uint32_t remaining = s->response_buffer->len - s->response_offset; - uint32_t to_copy = MIN(CRB_CTRL_CMD_SIZE, remaining); + uint32_t remaining = 0; + uint32_t to_copy; - memcpy(mem, s->response_buffer->data + s->response_offset, to_copy); + if (s->response_offset < s->response_buffer->len) { + remaining = s->response_buffer->len - s->response_offset; + } + to_copy = MIN(CRB_CTRL_CMD_SIZE, remaining); + + if (to_copy) { + memcpy(mem, s->response_buffer->data + s->response_offset, to_copy); + } if (to_copy < CRB_CTRL_CMD_SIZE) { memset((guint8 *)mem + to_copy, 0, CRB_CTRL_CMD_SIZE - to_copy); -- 2.55.0
