qemu with hax to log dma reads & writes jcs.org/2018/11/12/vfio

Merge remote-tracking branch 'remotes/maxreitz/tags/pull-block-2020-03-24' into staging

Block patches for 5.0-rc0:
- Use-after-free fix
- Fix for a memleak in an error path
- Preventative measures against other potential use-after-frees, and
against NULL deferences at runtime
- iotest fixes

# gpg: Signature made Tue 24 Mar 2020 12:19:09 GMT
# gpg: using RSA key 91BEB60A30DB3E8857D11829F407DB0061D5CF40
# gpg: issuer "mreitz@redhat.com"
# gpg: Good signature from "Max Reitz <mreitz@redhat.com>" [full]
# Primary key fingerprint: 91BE B60A 30DB 3E88 57D1 1829 F407 DB00 61D5 CF40

* remotes/maxreitz/tags/pull-block-2020-03-24:
iotests/026: Move v3-exclusive test to new file
iotests: Fix cleanup path in some tests
block/qcow2: zero data_file child after free
block: bdrv_set_backing_bs: fix use-after-free
block: Assert BlockDriver::format_name is not NULL
block: Avoid memleak on qcow2 image info failure

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>

+111 -45
+2 -1
block.c
··· 363 363 364 364 void bdrv_register(BlockDriver *bdrv) 365 365 { 366 + assert(bdrv->format_name); 366 367 QLIST_INSERT_HEAD(&bdrv_drivers, bdrv, list); 367 368 } 368 369 ··· 2759 2760 2760 2761 if (bs->backing) { 2761 2762 bdrv_unref_child(bs, bs->backing); 2763 + bs->backing = NULL; 2762 2764 } 2763 2765 2764 2766 if (!backing_hd) { 2765 - bs->backing = NULL; 2766 2767 goto out; 2767 2768 } 2768 2769
+3
block/qcow2.c
··· 1758 1758 g_free(s->image_data_file); 1759 1759 if (has_data_file(bs)) { 1760 1760 bdrv_unref_child(bs, s->data_file); 1761 + s->data_file = NULL; 1761 1762 } 1762 1763 g_free(s->unknown_header_fields); 1763 1764 cleanup_unknown_header_ext(bs); ··· 2621 2622 2622 2623 if (has_data_file(bs)) { 2623 2624 bdrv_unref_child(bs, s->data_file); 2625 + s->data_file = NULL; 2624 2626 } 2625 2627 2626 2628 qcow2_refcount_close(bs); ··· 4811 4813 if (local_err) { 4812 4814 error_propagate(errp, local_err); 4813 4815 qapi_free_ImageInfoSpecific(spec_info); 4816 + qapi_free_QCryptoBlockInfo(encrypt_info); 4814 4817 return NULL; 4815 4818 } 4816 4819 *spec_info->u.qcow2.data = (ImageInfoSpecificQCow2){
-31
tests/qemu-iotests/026
··· 240 240 241 241 _check_test_img 242 242 243 - echo 244 - echo === Avoid freeing external data clusters on failure === 245 - echo 246 - 247 - # Similar test as the last one, except we test what happens when there 248 - # is an error when writing to an external data file instead of when 249 - # writing to a preallocated zero cluster 250 - _make_test_img -o "data_file=$TEST_IMG.data_file" $CLUSTER_SIZE 251 - 252 - # Put blkdebug above the data-file, and a raw node on top of that so 253 - # that blkdebug will see a write_aio event and emit an error 254 - $QEMU_IO -c "write 0 $CLUSTER_SIZE" \ 255 - "json:{ 256 - 'driver': 'qcow2', 257 - 'file': { 'driver': 'file', 'filename': '$TEST_IMG' }, 258 - 'data-file': { 259 - 'driver': 'raw', 260 - 'file': { 261 - 'driver': 'blkdebug', 262 - 'config': '$TEST_DIR/blkdebug.conf', 263 - 'image': { 264 - 'driver': 'file', 265 - 'filename': '$TEST_IMG.data_file' 266 - } 267 - } 268 - } 269 - }" \ 270 - | _filter_qemu_io 271 - 272 - _check_test_img 273 - 274 243 # success, all done 275 244 echo "*** done" 276 245 rm -f $seq.full
-6
tests/qemu-iotests/026.out
··· 653 653 1 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) 654 654 write failed: Input/output error 655 655 No errors were found on the image. 656 - 657 - === Avoid freeing external data clusters on failure === 658 - 659 - Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1024 data_file=TEST_DIR/t.IMGFMT.data_file 660 - write failed: Input/output error 661 - No errors were found on the image. 662 656 *** done
-6
tests/qemu-iotests/026.out.nocache
··· 661 661 1 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) 662 662 write failed: Input/output error 663 663 No errors were found on the image. 664 - 665 - === Avoid freeing external data clusters on failure === 666 - 667 - Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1024 data_file=TEST_DIR/t.IMGFMT.data_file 668 - write failed: Input/output error 669 - No errors were found on the image. 670 664 *** done
+1
tests/qemu-iotests/085
··· 39 39 _cleanup() 40 40 { 41 41 _cleanup_qemu 42 + _cleanup_test_img 42 43 for i in $(seq 1 ${SNAPSHOTS}) 43 44 do 44 45 _rm_test_img "${TEST_DIR}/${i}-${snapshot_virt0}"
+6
tests/qemu-iotests/087
··· 26 26 27 27 status=1 # failure is the default! 28 28 29 + _cleanup() 30 + { 31 + _cleanup_test_img 32 + } 33 + trap "_cleanup; exit \$status" 0 1 2 3 15 34 + 29 35 # get standard environment, filters and checks 30 36 . ./common.rc 31 37 . ./common.filter
+1 -1
tests/qemu-iotests/279
··· 26 26 _cleanup() 27 27 { 28 28 _cleanup_test_img 29 - rm -f "$TEST_IMG.mid" 29 + _rm_test_img "$TEST_IMG.mid" 30 30 } 31 31 trap "_cleanup; exit \$status" 0 1 2 3 15 32 32
+89
tests/qemu-iotests/289
··· 1 + #!/usr/bin/env bash 2 + # 3 + # qcow2 v3-exclusive error path testing 4 + # (026 tests paths common to v2 and v3) 5 + # 6 + # Copyright (C) 2020 Red Hat, Inc. 7 + # 8 + # This program is free software; you can redistribute it and/or modify 9 + # it under the terms of the GNU General Public License as published by 10 + # the Free Software Foundation; either version 2 of the License, or 11 + # (at your option) any later version. 12 + # 13 + # This program is distributed in the hope that it will be useful, 14 + # but WITHOUT ANY WARRANTY; without even the implied warranty of 15 + # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 + # GNU General Public License for more details. 17 + # 18 + # You should have received a copy of the GNU General Public License 19 + # along with this program. If not, see <http://www.gnu.org/licenses/>. 20 + # 21 + 22 + seq=$(basename $0) 23 + echo "QA output created by $seq" 24 + 25 + status=1 # failure is the default! 26 + 27 + _cleanup() 28 + { 29 + _cleanup_test_img 30 + rm "$TEST_DIR/blkdebug.conf" 31 + rm -f "$TEST_IMG.data_file" 32 + } 33 + trap "_cleanup; exit \$status" 0 1 2 3 15 34 + 35 + # get standard environment, filters and checks 36 + . ./common.rc 37 + . ./common.filter 38 + . ./common.pattern 39 + 40 + _supported_fmt qcow2 41 + _supported_proto file 42 + # This is a v3-exclusive test; 43 + # As for data_file, error paths often very much depend on whether 44 + # there is an external data file or not; so we create one exactly when 45 + # we want to test it 46 + _unsupported_imgopts 'compat=0.10' data_file 47 + 48 + echo 49 + echo === Avoid freeing external data clusters on failure === 50 + echo 51 + 52 + cat > "$TEST_DIR/blkdebug.conf" <<EOF 53 + [inject-error] 54 + event = "write_aio" 55 + errno = "5" 56 + once = "on" 57 + EOF 58 + 59 + # Test what happens when there is an error when writing to an external 60 + # data file instead of when writing to a preallocated zero cluster 61 + _make_test_img -o "data_file=$TEST_IMG.data_file" 64k 62 + 63 + # Put blkdebug above the data-file, and a raw node on top of that so 64 + # that blkdebug will see a write_aio event and emit an error. This 65 + # will then trigger the alloc abort code, which we want to test here. 66 + $QEMU_IO -c "write 0 64k" \ 67 + "json:{ 68 + 'driver': 'qcow2', 69 + 'file': { 'driver': 'file', 'filename': '$TEST_IMG' }, 70 + 'data-file': { 71 + 'driver': 'raw', 72 + 'file': { 73 + 'driver': 'blkdebug', 74 + 'config': '$TEST_DIR/blkdebug.conf', 75 + 'image': { 76 + 'driver': 'file', 77 + 'filename': '$TEST_IMG.data_file' 78 + } 79 + } 80 + } 81 + }" \ 82 + | _filter_qemu_io 83 + 84 + _check_test_img 85 + 86 + # success, all done 87 + echo "*** done" 88 + rm -f $seq.full 89 + status=0
+8
tests/qemu-iotests/289.out
··· 1 + QA output created by 289 2 + 3 + === Avoid freeing external data clusters on failure === 4 + 5 + Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=65536 data_file=TEST_DIR/t.IMGFMT.data_file 6 + write failed: Input/output error 7 + No errors were found on the image. 8 + *** done
+1
tests/qemu-iotests/group
··· 295 295 284 rw 296 296 286 rw quick 297 297 288 quick 298 + 289 rw quick