While the SB16 seems to work up to 48000 Hz, the "Sound Blaster Series
Hardware Programming Guide" limit the sampling range from 4000 Hz to
44100 Hz (Section 3-9, 3-10: Digitized Sound I/O Programming, tables
3-2 and 3-3).
Later, section 6-15 (DSP Commands) is more specific regarding the 41h /
42h registers (Set digitized sound output sampling rate):
Valid sampling rates range from 5000 to 45000 Hz inclusive.
There is no comment regarding error handling if the register is filled
with an out-of-range value. (See also section 3-28 "8-bit or 16-bit
Auto-initialize Transfer"). Assume limits are enforced in hardware.
This fixes triggering an assertion in audio_calloc():
While the SB16 seems to work up to 48000 Hz, the "Sound Blaster Series
Hardware Programming Guide" limit the sampling range from 4000 Hz to
44100 Hz (Section 3-9, 3-10: Digitized Sound I/O Programming, tables
3-2 and 3-3).
Later, section 6-15 (DSP Commands) is more specific regarding the 41h /
42h registers (Set digitized sound output sampling rate):
Valid sampling rates range from 5000 to 45000 Hz inclusive.
There is no comment regarding error handling if the register is filled
with an out-of-range value. (See also section 3-28 "8-bit or 16-bit
Auto-initialize Transfer"). Assume limits are enforced in hardware.
This fixes triggering an assertion in audio_calloc():
#1 abort sw_alloc_ resources_ out audio/audio_ template. h:116:15 sw_init_ out audio/audio_ template. h:175:11 create_ voice_pair_ out audio/audio_ template. h:410:9 template. h:503:14 sb16.c: 216:20 sb16.c: 276:5 sb16.c: 949:13 ioport. c:205:13 region_ write_accessor softmmu/ memory. c:491:5 with_adjusted_ size softmmu/ memory. c:552:18 region_ dispatch_ write softmmu/ memory. c:0:13 write_continue softmmu/ physmem. c:2759: 23 physmem. c:2799: 14 physmem. c:2891: 18 ioport. c:70:5
#2 audio_bug audio/audio.c:119:9
#3 audio_calloc audio/audio.c:154:9
#4 audio_pcm_
#5 audio_pcm_
#6 audio_pcm_
#7 AUD_open_out audio/audio_
#8 continue_dma8 hw/audio/
#9 dma_cmd8 hw/audio/
#10 command hw/audio/sb16.c:0
#11 dsp_write hw/audio/
#12 portio_write softmmu/
#13 memory_
#14 access_
#15 memory_
#16 flatview_
#17 flatview_write softmmu/
#18 address_space_write softmmu/
#19 cpu_outw softmmu/
[*] http:// www.baudline. com/solutions/ full_duplex/ sb16_pci/ index.html
Fixes: 85571bc7415 ("audio merge (malc)") /bugs.launchpad .net/bugs/ 1910603 /bugs.chromium. org/p/oss- fuzz/issues/ detail? id=29174 qtest/fuzz- sb16-test. c | 52 +++++++ +++++++ +++++++ +++++++ +++++++ + qtest/meson. build | 1 + fuzz-sb16- test.c
Buglink: https:/
OSS-Fuzz Report: https:/
Signed-off-by: Philippe Mathieu-Daudé <email address hidden>
---
hw/audio/sb16.c | 14 ++++++++++
tests/
MAINTAINERS | 1 +
tests/
4 files changed, 68 insertions(+)
create mode 100644 tests/qtest/
diff --git a/hw/audio/sb16.c b/hw/audio/sb16.c .5cf121fe363 100644
index 8b207004102.
--- a/hw/audio/sb16.c
+++ b/hw/audio/sb16.c
@@ -115,6 +115,9 @@ struct SB16State {
PortioList portio_list;
};
+#define SAMPLE_RATE_MIN 5000
+#define SAMPLE_RATE_MAX 45000
+
static void SB_audio_callback (void *opaque, int free);
static int magic_of_irq (int irq) mask(LOG_ GUEST_ERROR, mask(LOG_ GUEST_ERROR,
@@ -241,6 +244,17 @@ 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_
+ "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_
+ "sampling range too high: %d, decreasing to %u\n",
+ s->freq, SAMPLE_RATE_MAX);
+ s->freq = SAMPLE_RATE_MAX;
+ }
if (dma_len != -1) {
s->block_ size = dma_len << s->fmt_stereo; qtest/fuzz- sb16-test. c b/tests/ qtest/fuzz- sb16-test. c .51030cd7dc4 qtest/fuzz- sb16-test. c Identifier: GPL-2.0-or-later /bugs.launchpad .net/qemu/ +bug/1910603 sb16_0x1c( void) sb16_0x91( void) driver= none"); func("fuzz/ test_fuzz_ sb16/1c" , test_fuzz_ sb16_0x1c) ; func("fuzz/ test_fuzz_ sb16/91" , test_fuzz_ sb16_0x91) ; .7edb26d2293 100644 ac97-test. c es1370- test.c intel-hda- test.c fuzz-sb16- test.c
diff --git a/tests/
new file mode 100644
index 00000000000.
--- /dev/null
+++ b/tests/
@@ -0,0 +1,52 @@
+/*
+ * QTest fuzzer-generated testcase for sb16 audio device
+ *
+ * Copyright (c) 2021 Philippe Mathieu-Daudé <email address hidden>
+ *
+ * SPDX-License-
+ */
+
+#include "qemu/osdep.h"
+#include "libqos/libqtest.h"
+
+/*
+ * This used to trigger the assert in audio_calloc
+ * https:/
+ */
+static void test_fuzz_
+{
+ QTestState *s = qtest_init("-M q35 -display none "
+ "-device sb16,audiodev=snd0 "
+ "-audiodev none,id=snd0");
+ qtest_outw(s, 0x22c, 0x41);
+ qtest_outb(s, 0x22c, 0x00);
+ qtest_outw(s, 0x22c, 0x1004);
+ qtest_outw(s, 0x22c, 0x001c);
+ qtest_quit(s);
+}
+
+static void test_fuzz_
+{
+ QTestState *s = qtest_init("-M pc -display none "
+ "-device sb16,audiodev=none "
+ "-audiodev id=none,
+ qtest_outw(s, 0x22c, 0xf141);
+ qtest_outb(s, 0x22c, 0x00);
+ qtest_outb(s, 0x22c, 0x24);
+ qtest_outb(s, 0x22c, 0x91);
+ qtest_quit(s);
+}
+
+int main(int argc, char **argv)
+{
+ const char *arch = qtest_get_arch();
+
+ g_test_init(&argc, &argv, NULL);
+
+ if (strcmp(arch, "i386") == 0) {
+ qtest_add_
+ qtest_add_
+ }
+
+ return g_test_run();
+}
diff --git a/MAINTAINERS b/MAINTAINERS
index 5f55404f2fa.
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2213,6 +2213,7 @@ F: qapi/audio.json
F: tests/qtest/
F: tests/qtest/
F: tests/qtest/
+F: tests/qtest/
Block layer core qtest/meson. build b/tests/ qtest/meson. build .b03e8541700 100644 qtest/meson. build qtest/meson. build all_devices. has_key( 'CONFIG_ MEGASAS_ SCSI_PCI' ) ? ['fuzz- megasas- test'] : []) + \ all_devices. has_key( 'CONFIG_ VIRTIO_ SCSI') ? ['fuzz- virtio- scsi-test' ] : []) + \ all_devices. has_key( 'CONFIG_ SB16') ? ['fuzz-sb16-test'] : []) + \ introspect- test',
M: Kevin Wolf <email address hidden>
diff --git a/tests/
index c3a223a83d6.
--- a/tests/
+++ b/tests/
@@ -20,6 +20,7 @@
qtests_generic = \
(config_
(config_
+ (config_
[
'cdrom-test',
'device-
--
2.26.3