From: Jenny Guanni Qu <[email protected]> The SB16 VMState loads in_index and out_data_len as raw INT32 values with no bounds validation. A crafted migration stream or VM snapshot can set these to values exceeding their respective buffer sizes (in2_data[10] and out_data[50]), causing heap OOB write in dsp_write() and heap OOB read in dsp_read().
Add bounds checks in sb16_post_load() to reject invalid values before they can be used as array indices. Resolves: https://gitlab.com/qemu-project/qemu/-/issues/3326 Reported-by: Jenny Guanni Qu <[email protected]> Signed-off-by: Jenny Guanni Qu <[email protected]> Link: https://lore.kernel.org/r/[email protected] Cc: [email protected] Signed-off-by: Paolo Bonzini <[email protected]> (cherry picked from commit cb1e8c18df625dc9aed7f5fd5c8b961e8e4d1023) Signed-off-by: Michael Tokarev <[email protected]> diff --git a/hw/audio/sb16.c b/hw/audio/sb16.c index 0c661b4947..85b869a50a 100644 --- a/hw/audio/sb16.c +++ b/hw/audio/sb16.c @@ -1287,6 +1287,13 @@ static int sb16_post_load (void *opaque, int version_id) { SB16State *s = opaque; + + if (s->in_index < 0 || s->in_index > (int)sizeof(s->in2_data)) { + return -1; + } + if (s->out_data_len < 0 || s->out_data_len > (int)sizeof(s->out_data)) { + return -1; + } if (s->voice) { AUD_close_out (&s->card, s->voice); s->voice = NULL; -- 2.47.3
