1. 27 2月, 2020 1 次提交
    • S
      virtio: gracefully handle invalid region caches · abdd16f4
      Stefan Hajnoczi 提交于
      The virtqueue code sets up MemoryRegionCaches to access the virtqueue
      guest RAM data structures.  The code currently assumes that
      VRingMemoryRegionCaches is initialized before device emulation code
      accesses the virtqueue.  An assertion will fail in
      vring_get_region_caches() when this is not true.  Device fuzzing found a
      case where this assumption is false (see below).
      
      Virtqueue guest RAM addresses can also be changed from a vCPU thread
      while an IOThread is accessing the virtqueue.  This breaks the same
      assumption but this time the caches could become invalid partway through
      the virtqueue code.  The code fetches the caches RCU pointer multiple
      times so we will need to validate the pointer every time it is fetched.
      
      Add checks each time we call vring_get_region_caches() and treat invalid
      caches as a nop: memory stores are ignored and memory reads return 0.
      
      The fuzz test failure is as follows:
      
        $ qemu -M pc -device virtio-blk-pci,id=drv0,drive=drive0,addr=4.0 \
               -drive if=none,id=drive0,file=null-co://,format=raw,auto-read-only=off \
               -drive if=none,id=drive1,file=null-co://,file.read-zeroes=on,format=raw \
               -display none \
               -qtest stdio
        endianness
        outl 0xcf8 0x80002020
        outl 0xcfc 0xe0000000
        outl 0xcf8 0x80002004
        outw 0xcfc 0x7
        write 0xe0000000 0x24 0x00ffffffabffffffabffffffabffffffabffffffabffffffabffffffabffffffabffffffabffffffabffffffabffffffabffffffabffffffab5cffffffabffffffabffffffabffffffabffffffabffffffabffffffabffffffabffffffabffffffabffffffabffffffabffffffabffffffabffffffab0000000001
        inb 0x4
        writew 0xe000001c 0x1
        write 0xe0000014 0x1 0x0d
      
      The following error message is produced:
      
        qemu-system-x86_64: /home/stefanha/qemu/hw/virtio/virtio.c:286: vring_get_region_caches: Assertion `caches != NULL' failed.
      
      The backtrace looks like this:
      
        #0  0x00007ffff5520625 in raise () at /lib64/libc.so.6
        #1  0x00007ffff55098d9 in abort () at /lib64/libc.so.6
        #2  0x00007ffff55097a9 in _nl_load_domain.cold () at /lib64/libc.so.6
        #3  0x00007ffff5518a66 in annobin_assert.c_end () at /lib64/libc.so.6
        #4  0x00005555559073da in vring_get_region_caches (vq=<optimized out>) at qemu/hw/virtio/virtio.c:286
        #5  vring_get_region_caches (vq=<optimized out>) at qemu/hw/virtio/virtio.c:283
        #6  0x000055555590818d in vring_used_flags_set_bit (mask=1, vq=0x5555575ceea0) at qemu/hw/virtio/virtio.c:398
        #7  virtio_queue_split_set_notification (enable=0, vq=0x5555575ceea0) at qemu/hw/virtio/virtio.c:398
        #8  virtio_queue_set_notification (vq=vq@entry=0x5555575ceea0, enable=enable@entry=0) at qemu/hw/virtio/virtio.c:451
        #9  0x0000555555908512 in virtio_queue_set_notification (vq=vq@entry=0x5555575ceea0, enable=enable@entry=0) at qemu/hw/virtio/virtio.c:444
        #10 0x00005555558c697a in virtio_blk_handle_vq (s=0x5555575c57e0, vq=0x5555575ceea0) at qemu/hw/block/virtio-blk.c:775
        #11 0x0000555555907836 in virtio_queue_notify_aio_vq (vq=0x5555575ceea0) at qemu/hw/virtio/virtio.c:2244
        #12 0x0000555555cb5dd7 in aio_dispatch_handlers (ctx=ctx@entry=0x55555671a420) at util/aio-posix.c:429
        #13 0x0000555555cb67a8 in aio_dispatch (ctx=0x55555671a420) at util/aio-posix.c:460
        #14 0x0000555555cb307e in aio_ctx_dispatch (source=<optimized out>, callback=<optimized out>, user_data=<optimized out>) at util/async.c:260
        #15 0x00007ffff7bbc510 in g_main_context_dispatch () at /lib64/libglib-2.0.so.0
        #16 0x0000555555cb5848 in glib_pollfds_poll () at util/main-loop.c:219
        #17 os_host_main_loop_wait (timeout=<optimized out>) at util/main-loop.c:242
        #18 main_loop_wait (nonblocking=<optimized out>) at util/main-loop.c:518
        #19 0x00005555559b20c9 in main_loop () at vl.c:1683
        #20 0x0000555555838115 in main (argc=<optimized out>, argv=<optimized out>, envp=<optimized out>) at vl.c:4441
      Reported-by: NAlexander Bulekov <alxndr@bu.edu>
      Cc: Michael Tsirkin <mst@redhat.com>
      Cc: Cornelia Huck <cohuck@redhat.com>
      Cc: Paolo Bonzini <pbonzini@redhat.com>
      Cc: qemu-stable@nongnu.org
      Signed-off-by: NStefan Hajnoczi <stefanha@redhat.com>
      Message-Id: <20200207104619.164892-1-stefanha@redhat.com>
      Reviewed-by: NMichael S. Tsirkin <mst@redhat.com>
      Signed-off-by: NMichael S. Tsirkin <mst@redhat.com>
      abdd16f4
  2. 25 2月, 2020 14 次提交
  3. 24 2月, 2020 1 次提交
    • P
      Merge remote-tracking branch 'remotes/stefanha/tags/block-pull-request' into staging · c1e667d2
      Peter Maydell 提交于
      Pull request
      
      This pull request contains a virtio-blk/scsi performance optimization, event
      loop scalability improvements, and a qtest-based device fuzzing framework.  I
      am including the fuzzing patches because I have reviewed them and Thomas Huth
      is currently away on leave.
      
      # gpg: Signature made Sat 22 Feb 2020 08:50:05 GMT
      # gpg:                using RSA key 8695A8BFD3F97CDAAC35775A9CA4ABB381AB73C8
      # gpg: Good signature from "Stefan Hajnoczi <stefanha@redhat.com>" [full]
      # gpg:                 aka "Stefan Hajnoczi <stefanha@gmail.com>" [full]
      # Primary key fingerprint: 8695 A8BF D3F9 7CDA AC35  775A 9CA4 ABB3 81AB 73C8
      
      * remotes/stefanha/tags/block-pull-request: (31 commits)
        fuzz: add documentation to docs/devel/
        fuzz: add virtio-scsi fuzz target
        fuzz: add virtio-net fuzz target
        fuzz: add i440fx fuzz targets
        fuzz: add configure flag --enable-fuzzing
        fuzz: add target/fuzz makefile rules
        fuzz: add support for qos-assisted fuzz targets
        fuzz: support for fork-based fuzzing.
        main: keep rcu_atfork callback enabled for qtest
        exec: keep ram block across fork when using qtest
        fuzz: add fuzzer skeleton
        libqos: move useful qos-test funcs to qos_external
        libqos: split qos-test and libqos makefile vars
        libqos: rename i2c_send and i2c_recv
        qtest: add in-process incoming command handler
        libqtest: make bufwrite rely on the TransportOps
        libqtest: add a layer of abstraction to send/recv
        qtest: add qtest_server_send abstraction
        fuzz: add FUZZ_TARGET module type
        module: check module wasn't already initialized
        ...
      Signed-off-by: NPeter Maydell <peter.maydell@linaro.org>
      c1e667d2
  4. 22 2月, 2020 24 次提交