From 60e543f5ce46d4a90a95963b3bab5c7d13a2aaa9 Mon Sep 17 00:00:00 2001 From: Qiang Liu Date: Thu, 24 Jun 2021 10:44:47 +0800 Subject: hw/audio/sb16: Restrict I/O sampling rate range for command 41h/42h MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The I/O sampling rate range is enforced to 5000 to 45000HZ according to commit a2cd86a9. Setting I/O sampling rate with command 41h/42h, a guest user can break this assumption and trigger an assertion in audio_calloc via command 0xd4. This patch restricts the I/O sampling rate range for command 41h/42h. Fixes: 85571bc7415 ("audio merge (malc)") Signed-off-by: Qiang Liu Message-Id: <1624502687-5214-1-git-send-email-cyruscyliu@gmail.com> Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Gerd Hoffmann --- hw/audio/sb16.c | 31 +++++++++++++++++++------------ 1 file changed, 19 insertions(+), 12 deletions(-) (limited to 'hw') diff --git a/hw/audio/sb16.c b/hw/audio/sb16.c index 5cf121f..60f1f75 100644 --- a/hw/audio/sb16.c +++ b/hw/audio/sb16.c @@ -229,6 +229,23 @@ static void continue_dma8 (SB16State *s) control (s, 1); } +static inline int restrict_sampling_rate(int freq) +{ + if (freq < SAMPLE_RATE_MIN) { + qemu_log_mask(LOG_GUEST_ERROR, + "sampling range too low: %d, increasing to %u\n", + freq, SAMPLE_RATE_MIN); + return SAMPLE_RATE_MIN; + } else if (freq > SAMPLE_RATE_MAX) { + qemu_log_mask(LOG_GUEST_ERROR, + "sampling range too high: %d, decreasing to %u\n", + freq, SAMPLE_RATE_MAX); + return SAMPLE_RATE_MAX; + } else { + return freq; + } +} + static void dma_cmd8 (SB16State *s, int mask, int dma_len) { s->fmt = AUDIO_FORMAT_U8; @@ -244,17 +261,7 @@ static void dma_cmd8 (SB16State *s, int mask, int dma_len) int tmp = (256 - s->time_const); s->freq = (1000000 + (tmp / 2)) / tmp; } - if (s->freq < SAMPLE_RATE_MIN) { - qemu_log_mask(LOG_GUEST_ERROR, - "sampling range too low: %d, increasing to %u\n", - s->freq, SAMPLE_RATE_MIN); - s->freq = SAMPLE_RATE_MIN; - } else if (s->freq > SAMPLE_RATE_MAX) { - qemu_log_mask(LOG_GUEST_ERROR, - "sampling range too high: %d, decreasing to %u\n", - s->freq, SAMPLE_RATE_MAX); - s->freq = SAMPLE_RATE_MAX; - } + s->freq = restrict_sampling_rate(s->freq); if (dma_len != -1) { s->block_size = dma_len << s->fmt_stereo; @@ -768,7 +775,7 @@ static void complete (SB16State *s) * and FT2 sets output freq with this (go figure). Compare: * http://homepages.cae.wisc.edu/~brodskye/sb16doc/sb16doc.html#SamplingRate */ - s->freq = dsp_get_hilo (s); + s->freq = restrict_sampling_rate(dsp_get_hilo(s)); ldebug ("set freq %d\n", s->freq); break; -- cgit v1.1