diff options
| author | Nicholas Piggin <npiggin@gmail.com> | 2025-03-17 13:18:29 +1000 |
|---|---|---|
| committer | Nicholas Piggin <npiggin@gmail.com> | 2025-03-20 19:55:13 +1000 |
| commit | 344921309d933547974c2e85c52e2294513d9c45 (patch) | |
| tree | 0e2b681cf419109808fb03c95c4b1be9392899dc /hw/intc/xive.c | |
| parent | 033a5649b45690d09bde5cdf15cb83453f6ac811 (diff) | |
| download | focaccia-qemu-344921309d933547974c2e85c52e2294513d9c45.tar.gz focaccia-qemu-344921309d933547974c2e85c52e2294513d9c45.zip | |
pnv/xive: Fix possible undefined shift error in group size calculation
Coverity discovered a potential shift overflow in group size calculation
in the case of a guest error. Add checks and logs to ensure a issues are
caught.
Make the group and crowd error checking code more similar to one another
while here.
Resolves: Coverity CID 1593724
Fixes: 9cb7f6ebed60 ("ppc/xive2: Support group-matching when looking for target")
Reviewed-by: Cédric Le Goater <clg@redhat.com>
Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
Diffstat (limited to 'hw/intc/xive.c')
| -rw-r--r-- | hw/intc/xive.c | 27 |
1 files changed, 24 insertions, 3 deletions
diff --git a/hw/intc/xive.c b/hw/intc/xive.c index e86f274932..3eb28c2265 100644 --- a/hw/intc/xive.c +++ b/hw/intc/xive.c @@ -1662,12 +1662,20 @@ uint32_t xive_get_vpgroup_size(uint32_t nvp_index) * (starting with the least significant bits) in the NVP index * gives the size of the group. */ - return 1 << (ctz32(~nvp_index) + 1); + int first_zero = cto32(nvp_index); + if (first_zero >= 31) { + qemu_log_mask(LOG_GUEST_ERROR, "XIVE: Invalid group index 0x%08x", + nvp_index); + return 0; + } + + return 1U << (first_zero + 1); } static uint8_t xive_get_group_level(bool crowd, bool ignore, uint32_t nvp_blk, uint32_t nvp_index) { + int first_zero; uint8_t level; if (!ignore) { @@ -1675,12 +1683,25 @@ static uint8_t xive_get_group_level(bool crowd, bool ignore, return 0; } - level = (ctz32(~nvp_index) + 1) & 0b1111; + first_zero = cto32(nvp_index); + if (first_zero >= 31) { + qemu_log_mask(LOG_GUEST_ERROR, "XIVE: Invalid group index 0x%08x", + nvp_index); + return 0; + } + + level = (first_zero + 1) & 0b1111; if (crowd) { uint32_t blk; /* crowd level is bit position of first 0 from the right in nvp_blk */ - blk = ctz32(~nvp_blk) + 1; + first_zero = cto32(nvp_blk); + if (first_zero >= 31) { + qemu_log_mask(LOG_GUEST_ERROR, "XIVE: Invalid crowd block 0x%08x", + nvp_blk); + return 0; + } + blk = first_zero + 1; /* * Supported crowd sizes are 2^1, 2^2, and 2^4. 2^3 is not supported. |