diff mbox series

[PATCH-for-6.2,2/2] tests/qtest/fdc-test: Add a regression test for CVE-2021-3507

Message ID 20211118115733.4038610-3-philmd@redhat.com
State New
Headers show
Series hw/block/fdc: Fix CVE-2021-3507 | expand

Commit Message

Philippe Mathieu-Daudé Nov. 18, 2021, 11:57 a.m. UTC
Add the reproducer from https://gitlab.com/qemu-project/qemu/-/issues/339

Without the previous commit, when running 'make check-qtest-i386'
with QEMU configured with '--enable-sanitizers' we get:

  ==4028352==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x619000062a00 at pc 0x5626d03c491a bp 0x7ffdb4199410 sp 0x7ffdb4198bc0
  READ of size 786432 at 0x619000062a00 thread T0
      #0 0x5626d03c4919 in __asan_memcpy (qemu-system-i386+0x1e65919)
      #1 0x5626d1c023cc in flatview_write_continue softmmu/physmem.c:2787:13
      #2 0x5626d1bf0c0f in flatview_write softmmu/physmem.c:2822:14
      #3 0x5626d1bf0798 in address_space_write softmmu/physmem.c:2914:18
      #4 0x5626d1bf0f37 in address_space_rw softmmu/physmem.c:2924:16
      #5 0x5626d1bf14c8 in cpu_physical_memory_rw softmmu/physmem.c:2933:5
      #6 0x5626d0bd5649 in cpu_physical_memory_write include/exec/cpu-common.h:82:5
      #7 0x5626d0bd0a07 in i8257_dma_write_memory hw/dma/i8257.c:452:9
      #8 0x5626d09f825d in fdctrl_transfer_handler hw/block/fdc.c:1616:13
      #9 0x5626d0a048b4 in fdctrl_start_transfer hw/block/fdc.c:1539:13
      #10 0x5626d09f4c3e in fdctrl_write_data hw/block/fdc.c:2266:13
      #11 0x5626d09f22f7 in fdctrl_write hw/block/fdc.c:829:9
      #12 0x5626d1c20bc5 in portio_write softmmu/ioport.c:207:17

  0x619000062a00 is located 0 bytes to the right of 512-byte region [0x619000062800,0x619000062a00)
  allocated by thread T0 here:
      #0 0x5626d03c66ec in posix_memalign (qemu-system-i386+0x1e676ec)
      #1 0x5626d2b988d4 in qemu_try_memalign util/oslib-posix.c:210:11
      #2 0x5626d2b98b0c in qemu_memalign util/oslib-posix.c:226:27
      #3 0x5626d09fbaf0 in fdctrl_realize_common hw/block/fdc.c:2341:20
      #4 0x5626d0a150ed in isabus_fdc_realize hw/block/fdc-isa.c:113:5
      #5 0x5626d2367935 in device_set_realized hw/core/qdev.c:531:13

  SUMMARY: AddressSanitizer: heap-buffer-overflow (qemu-system-i386+0x1e65919) in __asan_memcpy
  Shadow bytes around the buggy address:
    0x0c32800044f0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
    0x0c3280004500: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    0x0c3280004510: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    0x0c3280004520: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    0x0c3280004530: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  =>0x0c3280004540:[fa]fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
    0x0c3280004550: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
    0x0c3280004560: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
    0x0c3280004570: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
    0x0c3280004580: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
    0x0c3280004590: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  Shadow byte legend (one shadow byte represents 8 application bytes):
    Addressable:           00
    Heap left redzone:       fa
    Freed heap region:       fd
  ==4028352==ABORTING

Reported-by: Alexander Bulekov <alxndr@bu.edu>
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
---
 tests/qtest/fdc-test.c | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

Comments

Alexander Bulekov Nov. 23, 2021, 4:04 p.m. UTC | #1
On 211118 1257, Philippe Mathieu-Daudé wrote:
> Add the reproducer from https://gitlab.com/qemu-project/qemu/-/issues/339
> 
> Without the previous commit, when running 'make check-qtest-i386'
> with QEMU configured with '--enable-sanitizers' we get:
> 
>   ==4028352==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x619000062a00 at pc 0x5626d03c491a bp 0x7ffdb4199410 sp 0x7ffdb4198bc0
>   READ of size 786432 at 0x619000062a00 thread T0
>       #0 0x5626d03c4919 in __asan_memcpy (qemu-system-i386+0x1e65919)
>       #1 0x5626d1c023cc in flatview_write_continue softmmu/physmem.c:2787:13
>       #2 0x5626d1bf0c0f in flatview_write softmmu/physmem.c:2822:14
>       #3 0x5626d1bf0798 in address_space_write softmmu/physmem.c:2914:18
>       #4 0x5626d1bf0f37 in address_space_rw softmmu/physmem.c:2924:16
>       #5 0x5626d1bf14c8 in cpu_physical_memory_rw softmmu/physmem.c:2933:5
>       #6 0x5626d0bd5649 in cpu_physical_memory_write include/exec/cpu-common.h:82:5
>       #7 0x5626d0bd0a07 in i8257_dma_write_memory hw/dma/i8257.c:452:9
>       #8 0x5626d09f825d in fdctrl_transfer_handler hw/block/fdc.c:1616:13
>       #9 0x5626d0a048b4 in fdctrl_start_transfer hw/block/fdc.c:1539:13
>       #10 0x5626d09f4c3e in fdctrl_write_data hw/block/fdc.c:2266:13
>       #11 0x5626d09f22f7 in fdctrl_write hw/block/fdc.c:829:9
>       #12 0x5626d1c20bc5 in portio_write softmmu/ioport.c:207:17
> 
>   0x619000062a00 is located 0 bytes to the right of 512-byte region [0x619000062800,0x619000062a00)
>   allocated by thread T0 here:
>       #0 0x5626d03c66ec in posix_memalign (qemu-system-i386+0x1e676ec)
>       #1 0x5626d2b988d4 in qemu_try_memalign util/oslib-posix.c:210:11
>       #2 0x5626d2b98b0c in qemu_memalign util/oslib-posix.c:226:27
>       #3 0x5626d09fbaf0 in fdctrl_realize_common hw/block/fdc.c:2341:20
>       #4 0x5626d0a150ed in isabus_fdc_realize hw/block/fdc-isa.c:113:5
>       #5 0x5626d2367935 in device_set_realized hw/core/qdev.c:531:13
> 
>   SUMMARY: AddressSanitizer: heap-buffer-overflow (qemu-system-i386+0x1e65919) in __asan_memcpy
>   Shadow bytes around the buggy address:
>     0x0c32800044f0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
>     0x0c3280004500: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
>     0x0c3280004510: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
>     0x0c3280004520: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
>     0x0c3280004530: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
>   =>0x0c3280004540:[fa]fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
>     0x0c3280004550: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
>     0x0c3280004560: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
>     0x0c3280004570: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
>     0x0c3280004580: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
>     0x0c3280004590: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
>   Shadow byte legend (one shadow byte represents 8 application bytes):
>     Addressable:           00
>     Heap left redzone:       fa
>     Freed heap region:       fd
>   ==4028352==ABORTING
> 
> Reported-by: Alexander Bulekov <alxndr@bu.edu>
> Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
> ---
>  tests/qtest/fdc-test.c | 20 ++++++++++++++++++++
>  1 file changed, 20 insertions(+)
> 
> diff --git a/tests/qtest/fdc-test.c b/tests/qtest/fdc-test.c
> index 26b69f7c5cd..f164d972d10 100644
> --- a/tests/qtest/fdc-test.c
> +++ b/tests/qtest/fdc-test.c
> @@ -546,6 +546,25 @@ static void fuzz_registers(void)
>      }
>  }
>  
> +static void test_cve_2021_3507(void)
> +{
> +    QTestState *s;
> +
> +    s = qtest_initf("-nographic -m 32M -nodefaults "
> +                    "-drive file=%s,format=raw,if=floppy", test_image);

Does it make sense to run this with -snapshot ?

Reviewed-by: Alexander Bulekov <alxndr@bu.edu>

> +    qtest_outl(s, 0x9, 0x0a0206);
> +    qtest_outw(s, 0x3f4, 0x1600);
> +    qtest_outw(s, 0x3f4, 0x0000);
> +    qtest_outw(s, 0x3f4, 0x0000);
> +    qtest_outw(s, 0x3f4, 0x0000);
> +    qtest_outw(s, 0x3f4, 0x0200);
> +    qtest_outw(s, 0x3f4, 0x0200);
> +    qtest_outw(s, 0x3f4, 0x0000);
> +    qtest_outw(s, 0x3f4, 0x0000);
> +    qtest_outw(s, 0x3f4, 0x0000);
> +    qtest_quit(s);
> +}
> +
>  int main(int argc, char **argv)
>  {
>      int fd;
> @@ -576,6 +595,7 @@ int main(int argc, char **argv)
>      qtest_add_func("/fdc/read_no_dma_18", test_read_no_dma_18);
>      qtest_add_func("/fdc/read_no_dma_19", test_read_no_dma_19);
>      qtest_add_func("/fdc/fuzz-registers", fuzz_registers);
> +    qtest_add_func("/fdc/fuzz/cve_2021_3507", test_cve_2021_3507);
>  
>      ret = g_test_run();
>  
> -- 
> 2.31.1
>
Hanna Czenczek Nov. 23, 2021, 4:08 p.m. UTC | #2
On 18.11.21 12:57, Philippe Mathieu-Daudé wrote:
> Add the reproducer from https://gitlab.com/qemu-project/qemu/-/issues/339
>
> Without the previous commit, when running 'make check-qtest-i386'
> with QEMU configured with '--enable-sanitizers' we get:
>
>    ==4028352==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x619000062a00 at pc 0x5626d03c491a bp 0x7ffdb4199410 sp 0x7ffdb4198bc0
>    READ of size 786432 at 0x619000062a00 thread T0
>        #0 0x5626d03c4919 in __asan_memcpy (qemu-system-i386+0x1e65919)
>        #1 0x5626d1c023cc in flatview_write_continue softmmu/physmem.c:2787:13
>        #2 0x5626d1bf0c0f in flatview_write softmmu/physmem.c:2822:14
>        #3 0x5626d1bf0798 in address_space_write softmmu/physmem.c:2914:18
>        #4 0x5626d1bf0f37 in address_space_rw softmmu/physmem.c:2924:16
>        #5 0x5626d1bf14c8 in cpu_physical_memory_rw softmmu/physmem.c:2933:5
>        #6 0x5626d0bd5649 in cpu_physical_memory_write include/exec/cpu-common.h:82:5
>        #7 0x5626d0bd0a07 in i8257_dma_write_memory hw/dma/i8257.c:452:9
>        #8 0x5626d09f825d in fdctrl_transfer_handler hw/block/fdc.c:1616:13
>        #9 0x5626d0a048b4 in fdctrl_start_transfer hw/block/fdc.c:1539:13
>        #10 0x5626d09f4c3e in fdctrl_write_data hw/block/fdc.c:2266:13
>        #11 0x5626d09f22f7 in fdctrl_write hw/block/fdc.c:829:9
>        #12 0x5626d1c20bc5 in portio_write softmmu/ioport.c:207:17
>
>    0x619000062a00 is located 0 bytes to the right of 512-byte region [0x619000062800,0x619000062a00)
>    allocated by thread T0 here:
>        #0 0x5626d03c66ec in posix_memalign (qemu-system-i386+0x1e676ec)
>        #1 0x5626d2b988d4 in qemu_try_memalign util/oslib-posix.c:210:11
>        #2 0x5626d2b98b0c in qemu_memalign util/oslib-posix.c:226:27
>        #3 0x5626d09fbaf0 in fdctrl_realize_common hw/block/fdc.c:2341:20
>        #4 0x5626d0a150ed in isabus_fdc_realize hw/block/fdc-isa.c:113:5
>        #5 0x5626d2367935 in device_set_realized hw/core/qdev.c:531:13
>
>    SUMMARY: AddressSanitizer: heap-buffer-overflow (qemu-system-i386+0x1e65919) in __asan_memcpy
>    Shadow bytes around the buggy address:
>      0x0c32800044f0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
>      0x0c3280004500: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
>      0x0c3280004510: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
>      0x0c3280004520: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
>      0x0c3280004530: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
>    =>0x0c3280004540:[fa]fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
>      0x0c3280004550: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
>      0x0c3280004560: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
>      0x0c3280004570: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
>      0x0c3280004580: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
>      0x0c3280004590: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
>    Shadow byte legend (one shadow byte represents 8 application bytes):
>      Addressable:           00
>      Heap left redzone:       fa
>      Freed heap region:       fd
>    ==4028352==ABORTING
>
> Reported-by: Alexander Bulekov <alxndr@bu.edu>
> Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
> ---
>   tests/qtest/fdc-test.c | 20 ++++++++++++++++++++
>   1 file changed, 20 insertions(+)
>
> diff --git a/tests/qtest/fdc-test.c b/tests/qtest/fdc-test.c
> index 26b69f7c5cd..f164d972d10 100644
> --- a/tests/qtest/fdc-test.c
> +++ b/tests/qtest/fdc-test.c
> @@ -546,6 +546,25 @@ static void fuzz_registers(void)
>       }
>   }
>   
> +static void test_cve_2021_3507(void)
> +{
> +    QTestState *s;
> +
> +    s = qtest_initf("-nographic -m 32M -nodefaults "
> +                    "-drive file=%s,format=raw,if=floppy", test_image);
> +    qtest_outl(s, 0x9, 0x0a0206);
> +    qtest_outw(s, 0x3f4, 0x1600);
> +    qtest_outw(s, 0x3f4, 0x0000);
> +    qtest_outw(s, 0x3f4, 0x0000);
> +    qtest_outw(s, 0x3f4, 0x0000);
> +    qtest_outw(s, 0x3f4, 0x0200);
> +    qtest_outw(s, 0x3f4, 0x0200);
> +    qtest_outw(s, 0x3f4, 0x0000);
> +    qtest_outw(s, 0x3f4, 0x0000);
> +    qtest_outw(s, 0x3f4, 0x0000);

No idea what this does (looks like a 256-byte sector read read from 
sector 2 with EOT=0), but hits the problem and reproduces for me.

Unfortunately, I have the exact same problem with test_image as I did in 
the other series.

Hanna

> +    qtest_quit(s);
> +}
> +
>   int main(int argc, char **argv)
>   {
>       int fd;
> @@ -576,6 +595,7 @@ int main(int argc, char **argv)
>       qtest_add_func("/fdc/read_no_dma_18", test_read_no_dma_18);
>       qtest_add_func("/fdc/read_no_dma_19", test_read_no_dma_19);
>       qtest_add_func("/fdc/fuzz-registers", fuzz_registers);
> +    qtest_add_func("/fdc/fuzz/cve_2021_3507", test_cve_2021_3507);
>   
>       ret = g_test_run();
>
John Snow Nov. 24, 2021, 11:27 p.m. UTC | #3
On Tue, Nov 23, 2021 at 11:08 AM Hanna Reitz <hreitz@redhat.com> wrote:

> On 18.11.21 12:57, Philippe Mathieu-Daudé wrote:
> > Add the reproducer from
> https://gitlab.com/qemu-project/qemu/-/issues/339
> >
> > Without the previous commit, when running 'make check-qtest-i386'
> > with QEMU configured with '--enable-sanitizers' we get:
> >
> >    ==4028352==ERROR: AddressSanitizer: heap-buffer-overflow on address
> 0x619000062a00 at pc 0x5626d03c491a bp 0x7ffdb4199410 sp 0x7ffdb4198bc0
> >    READ of size 786432 at 0x619000062a00 thread T0
> >        #0 0x5626d03c4919 in __asan_memcpy (qemu-system-i386+0x1e65919)
> >        #1 0x5626d1c023cc in flatview_write_continue
> softmmu/physmem.c:2787:13
> >        #2 0x5626d1bf0c0f in flatview_write softmmu/physmem.c:2822:14
> >        #3 0x5626d1bf0798 in address_space_write softmmu/physmem.c:2914:18
> >        #4 0x5626d1bf0f37 in address_space_rw softmmu/physmem.c:2924:16
> >        #5 0x5626d1bf14c8 in cpu_physical_memory_rw
> softmmu/physmem.c:2933:5
> >        #6 0x5626d0bd5649 in cpu_physical_memory_write
> include/exec/cpu-common.h:82:5
> >        #7 0x5626d0bd0a07 in i8257_dma_write_memory hw/dma/i8257.c:452:9
> >        #8 0x5626d09f825d in fdctrl_transfer_handler
> hw/block/fdc.c:1616:13
> >        #9 0x5626d0a048b4 in fdctrl_start_transfer hw/block/fdc.c:1539:13
> >        #10 0x5626d09f4c3e in fdctrl_write_data hw/block/fdc.c:2266:13
> >        #11 0x5626d09f22f7 in fdctrl_write hw/block/fdc.c:829:9
> >        #12 0x5626d1c20bc5 in portio_write softmmu/ioport.c:207:17
> >
> >    0x619000062a00 is located 0 bytes to the right of 512-byte region
> [0x619000062800,0x619000062a00)
> >    allocated by thread T0 here:
> >        #0 0x5626d03c66ec in posix_memalign (qemu-system-i386+0x1e676ec)
> >        #1 0x5626d2b988d4 in qemu_try_memalign util/oslib-posix.c:210:11
> >        #2 0x5626d2b98b0c in qemu_memalign util/oslib-posix.c:226:27
> >        #3 0x5626d09fbaf0 in fdctrl_realize_common hw/block/fdc.c:2341:20
> >        #4 0x5626d0a150ed in isabus_fdc_realize hw/block/fdc-isa.c:113:5
> >        #5 0x5626d2367935 in device_set_realized hw/core/qdev.c:531:13
> >
> >    SUMMARY: AddressSanitizer: heap-buffer-overflow
> (qemu-system-i386+0x1e65919) in __asan_memcpy
> >    Shadow bytes around the buggy address:
> >      0x0c32800044f0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
> >      0x0c3280004500: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> >      0x0c3280004510: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> >      0x0c3280004520: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> >      0x0c3280004530: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> >    =>0x0c3280004540:[fa]fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
> >      0x0c3280004550: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
> >      0x0c3280004560: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
> >      0x0c3280004570: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
> >      0x0c3280004580: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
> >      0x0c3280004590: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
> >    Shadow byte legend (one shadow byte represents 8 application bytes):
> >      Addressable:           00
> >      Heap left redzone:       fa
> >      Freed heap region:       fd
> >    ==4028352==ABORTING
> >
> > Reported-by: Alexander Bulekov <alxndr@bu.edu>
> > Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
> > ---
> >   tests/qtest/fdc-test.c | 20 ++++++++++++++++++++
> >   1 file changed, 20 insertions(+)
> >
> > diff --git a/tests/qtest/fdc-test.c b/tests/qtest/fdc-test.c
> > index 26b69f7c5cd..f164d972d10 100644
> > --- a/tests/qtest/fdc-test.c
> > +++ b/tests/qtest/fdc-test.c
> > @@ -546,6 +546,25 @@ static void fuzz_registers(void)
> >       }
> >   }
> >
> > +static void test_cve_2021_3507(void)
> > +{
> > +    QTestState *s;
> > +
> > +    s = qtest_initf("-nographic -m 32M -nodefaults "
> > +                    "-drive file=%s,format=raw,if=floppy", test_image);
> > +    qtest_outl(s, 0x9, 0x0a0206);
> > +    qtest_outw(s, 0x3f4, 0x1600);
> > +    qtest_outw(s, 0x3f4, 0x0000);
> > +    qtest_outw(s, 0x3f4, 0x0000);
> > +    qtest_outw(s, 0x3f4, 0x0000);
> > +    qtest_outw(s, 0x3f4, 0x0200);
> > +    qtest_outw(s, 0x3f4, 0x0200);
> > +    qtest_outw(s, 0x3f4, 0x0000);
> > +    qtest_outw(s, 0x3f4, 0x0000);
> > +    qtest_outw(s, 0x3f4, 0x0000);
>
> No idea what this does (looks like a 256-byte sector read read from
> sector 2 with EOT=0), but hits the problem and reproduces for me.
>
> Unfortunately, I have the exact same problem with test_image as I did in
> the other series.
>
> Hanna
>
> > +    qtest_quit(s);
> > +}
> > +
> >   int main(int argc, char **argv)
> >   {
> >       int fd;
> > @@ -576,6 +595,7 @@ int main(int argc, char **argv)
> >       qtest_add_func("/fdc/read_no_dma_18", test_read_no_dma_18);
> >       qtest_add_func("/fdc/read_no_dma_19", test_read_no_dma_19);
> >       qtest_add_func("/fdc/fuzz-registers", fuzz_registers);
> > +    qtest_add_func("/fdc/fuzz/cve_2021_3507", test_cve_2021_3507);
> >
> >       ret = g_test_run();
> >
>

OK, I won't pull this one if there's a question over the suitability of the
test. I'm going to be away for the holiday until Monday, though. If the two
of you can agree that the fix and the test are good, though, I definitely
won't care if someone sends a PR for it.
diff mbox series

Patch

diff --git a/tests/qtest/fdc-test.c b/tests/qtest/fdc-test.c
index 26b69f7c5cd..f164d972d10 100644
--- a/tests/qtest/fdc-test.c
+++ b/tests/qtest/fdc-test.c
@@ -546,6 +546,25 @@  static void fuzz_registers(void)
     }
 }
 
+static void test_cve_2021_3507(void)
+{
+    QTestState *s;
+
+    s = qtest_initf("-nographic -m 32M -nodefaults "
+                    "-drive file=%s,format=raw,if=floppy", test_image);
+    qtest_outl(s, 0x9, 0x0a0206);
+    qtest_outw(s, 0x3f4, 0x1600);
+    qtest_outw(s, 0x3f4, 0x0000);
+    qtest_outw(s, 0x3f4, 0x0000);
+    qtest_outw(s, 0x3f4, 0x0000);
+    qtest_outw(s, 0x3f4, 0x0200);
+    qtest_outw(s, 0x3f4, 0x0200);
+    qtest_outw(s, 0x3f4, 0x0000);
+    qtest_outw(s, 0x3f4, 0x0000);
+    qtest_outw(s, 0x3f4, 0x0000);
+    qtest_quit(s);
+}
+
 int main(int argc, char **argv)
 {
     int fd;
@@ -576,6 +595,7 @@  int main(int argc, char **argv)
     qtest_add_func("/fdc/read_no_dma_18", test_read_no_dma_18);
     qtest_add_func("/fdc/read_no_dma_19", test_read_no_dma_19);
     qtest_add_func("/fdc/fuzz-registers", fuzz_registers);
+    qtest_add_func("/fdc/fuzz/cve_2021_3507", test_cve_2021_3507);
 
     ret = g_test_run();