diff options
author | Stefan Hajnoczi <stefanha@redhat.com> | 2021-02-23 14:46:53 +0000 |
---|---|---|
committer | Kevin Wolf <kwolf@redhat.com> | 2021-03-08 14:56:54 +0100 |
commit | 05ae4e674e3d47342a7660ae7bc55b393e09f4c7 (patch) | |
tree | 5c60b3bdf0125e43f6a5d9f8f31b3eae6ae5fd0f /block | |
parent | db4eadf9f10e19f864d70d1df3a90fbda31b8c06 (diff) | |
download | qemu-05ae4e674e3d47342a7660ae7bc55b393e09f4c7.zip qemu-05ae4e674e3d47342a7660ae7bc55b393e09f4c7.tar.gz qemu-05ae4e674e3d47342a7660ae7bc55b393e09f4c7.tar.bz2 |
block/export: port virtio-blk read/write range check
Check that the sector number and byte count are valid.
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Message-Id: <20210223144653.811468-13-stefanha@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Diffstat (limited to 'block')
-rw-r--r-- | block/export/vhost-user-blk-server.c | 19 |
1 files changed, 16 insertions, 3 deletions
diff --git a/block/export/vhost-user-blk-server.c b/block/export/vhost-user-blk-server.c index 0404422..cb5d896 100644 --- a/block/export/vhost-user-blk-server.c +++ b/block/export/vhost-user-blk-server.c @@ -209,6 +209,8 @@ static void coroutine_fn vu_blk_virtio_process_req(void *opaque) switch (type & ~VIRTIO_BLK_T_BARRIER) { case VIRTIO_BLK_T_IN: case VIRTIO_BLK_T_OUT: { + QEMUIOVector qiov; + int64_t offset; ssize_t ret = 0; bool is_write = type & VIRTIO_BLK_T_OUT; req->sector_num = le64_to_cpu(req->out.sector); @@ -218,13 +220,24 @@ static void coroutine_fn vu_blk_virtio_process_req(void *opaque) break; } - int64_t offset = req->sector_num << VIRTIO_BLK_SECTOR_BITS; - QEMUIOVector qiov; if (is_write) { qemu_iovec_init_external(&qiov, out_iov, out_num); - ret = blk_co_pwritev(blk, offset, qiov.size, &qiov, 0); } else { qemu_iovec_init_external(&qiov, in_iov, in_num); + } + + if (unlikely(!vu_blk_sect_range_ok(vexp, + req->sector_num, + qiov.size))) { + req->in->status = VIRTIO_BLK_S_IOERR; + break; + } + + offset = req->sector_num << VIRTIO_BLK_SECTOR_BITS; + + if (is_write) { + ret = blk_co_pwritev(blk, offset, qiov.size, &qiov, 0); + } else { ret = blk_co_preadv(blk, offset, qiov.size, &qiov, 0); } if (ret >= 0) { |