aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicholas Piggin <npiggin@gmail.com>2024-08-07 01:13:21 +1000
committerNicholas Piggin <npiggin@gmail.com>2024-11-04 09:08:58 +1000
commitddd2a060a0da41000ddca31e329ab1d54e37fedb (patch)
treef3615335329066e3879f106953a2497295e890a1
parentfdd9cf281d6c07c23f620d14896f97de6c4356b9 (diff)
ppc/pnv: ADU fix possible buffer overrun with invalid size
The ADU LPC transfer-size field is 7 bits, but the supported sizes for LPC access via ADU appear to be 1, 2, 4, 8. The data buffer could overrun if firmware set an invalid size field, so add checks to reject them with a message. Cc: qemu-stable@nongnu.org Reported-by: Cédric Le Goater <clg@redhat.com> Resolves: Coverity CID 1558830 Fixes: 24bd283bccb33 ("ppc/pnv: Implement ADU access to LPC space") Reviewed-by: Cédric Le Goater <clg@redhat.com> Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
-rw-r--r--hw/ppc/pnv_adu.c12
1 files changed, 12 insertions, 0 deletions
diff --git a/hw/ppc/pnv_adu.c b/hw/ppc/pnv_adu.c
index 81b7d6e526..f636dedf79 100644
--- a/hw/ppc/pnv_adu.c
+++ b/hw/ppc/pnv_adu.c
@@ -116,6 +116,12 @@ static void pnv_adu_xscom_write(void *opaque, hwaddr addr, uint64_t val,
uint32_t lpc_size = lpc_cmd_size(adu);
uint64_t data = 0;
+ if (!is_power_of_2(lpc_size) || lpc_size > sizeof(data)) {
+ qemu_log_mask(LOG_GUEST_ERROR, "ADU: Unsupported LPC access "
+ "size:%" PRId32 "\n", lpc_size);
+ break;
+ }
+
pnv_lpc_opb_read(adu->lpc, lpc_addr, (void *)&data, lpc_size);
/*
@@ -135,6 +141,12 @@ static void pnv_adu_xscom_write(void *opaque, hwaddr addr, uint64_t val,
uint32_t lpc_size = lpc_cmd_size(adu);
uint64_t data;
+ if (!is_power_of_2(lpc_size) || lpc_size > sizeof(data)) {
+ qemu_log_mask(LOG_GUEST_ERROR, "ADU: Unsupported LPC access "
+ "size:%" PRId32 "\n", lpc_size);
+ break;
+ }
+
data = cpu_to_be64(val) >> ((lpc_addr & 7) * 8); /* See above */
pnv_lpc_opb_write(adu->lpc, lpc_addr, (void *)&data, lpc_size);
}