From f5733366272225514266dfa4d38d431fe0d234a8 Mon Sep 17 00:00:00 2001 From: luffyluo Date: Sat, 21 Sep 2024 16:04:53 +0800 Subject: [PATCH] Fix CVE-2024-3567 CVE-2024-4467 CVE-2024-6505 CVE-2024-7730 --- ...t-Fix-overrun-in-update_sctp_checksu.patch | 68 +++++ ...n-t-open-data_file-with-BDRV_O_NO_IO.patch | 108 ++++++++ ...t-store-data-file-with-protocol-in-i.patch | 51 ++++ ...t-store-data-file-with-json-prefix-i.patch | 53 ++++ ...names-only-when-explicitly-requested.patch | 247 ++++++++++++++++++ ...net-Ensure-queue-index-fits-with-RSS.patch | 33 +++ ...dd-max-size-bounds-check-in-input-cb.patch | 58 ++++ qemu.spec | 23 +- 8 files changed, 640 insertions(+), 1 deletion(-) create mode 100644 CVE-2024-3567-hw-net-net_tx_pkt-Fix-overrun-in-update_sctp_checksu.patch create mode 100644 CVE-2024-4467-0001-qcow2-Don-t-open-data_file-with-BDRV_O_NO_IO.patch create mode 100644 CVE-2024-4467-0002-iotests-244-Don-t-store-data-file-with-protocol-in-i.patch create mode 100644 CVE-2024-4467-0003-iotests-270-Don-t-store-data-file-with-json-prefix-i.patch create mode 100644 CVE-2024-4467-0004-block-Parse-filenames-only-when-explicitly-requested.patch create mode 100644 CVE-2024-6505-virtio-net-Ensure-queue-index-fits-with-RSS.patch create mode 100644 CVE-2024-7730-virtio-snd-add-max-size-bounds-check-in-input-cb.patch diff --git a/CVE-2024-3567-hw-net-net_tx_pkt-Fix-overrun-in-update_sctp_checksu.patch b/CVE-2024-3567-hw-net-net_tx_pkt-Fix-overrun-in-update_sctp_checksu.patch new file mode 100644 index 0000000..f1dffc4 --- /dev/null +++ b/CVE-2024-3567-hw-net-net_tx_pkt-Fix-overrun-in-update_sctp_checksu.patch @@ -0,0 +1,68 @@ +From 83ddb3dbba2ee0f1767442ae6ee665058aeb1093 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= +Date: Tue, 9 Apr 2024 19:54:05 +0200 +Subject: [PATCH] hw/net/net_tx_pkt: Fix overrun in update_sctp_checksum() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +If a fragmented packet size is too short, do not try to +calculate its checksum. + +Reproduced using: + + $ cat << EOF | qemu-system-i386 -display none -nodefaults \ + -machine q35,accel=qtest -m 32M \ + -device igb,netdev=net0 \ + -netdev user,id=net0 \ + -qtest stdio + outl 0xcf8 0x80000810 + outl 0xcfc 0xe0000000 + outl 0xcf8 0x80000804 + outw 0xcfc 0x06 + write 0xe0000403 0x1 0x02 + writel 0xe0003808 0xffffffff + write 0xe000381a 0x1 0x5b + write 0xe000381b 0x1 0x00 + EOF + Assertion failed: (offset == 0), function iov_from_buf_full, file util/iov.c, line 39. + #1 0x5575e81e952a in iov_from_buf_full qemu/util/iov.c:39:5 + #2 0x5575e6500768 in net_tx_pkt_update_sctp_checksum qemu/hw/net/net_tx_pkt.c:144:9 + #3 0x5575e659f3e1 in igb_setup_tx_offloads qemu/hw/net/igb_core.c:478:11 + #4 0x5575e659f3e1 in igb_tx_pkt_send qemu/hw/net/igb_core.c:552:10 + #5 0x5575e659f3e1 in igb_process_tx_desc qemu/hw/net/igb_core.c:671:17 + #6 0x5575e659f3e1 in igb_start_xmit qemu/hw/net/igb_core.c:903:9 + #7 0x5575e659f3e1 in igb_set_tdt qemu/hw/net/igb_core.c:2812:5 + #8 0x5575e657d6a4 in igb_core_write qemu/hw/net/igb_core.c:4248:9 + +Fixes: CVE-2024-3567 +Cc: qemu-stable@nongnu.org +Reported-by: Zheyu Ma +Fixes: f199b13bc1 ("igb: Implement Tx SCTP CSO") +Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2273 +Signed-off-by: Philippe Mathieu-Daudé +Reviewed-by: Akihiko Odaki +Acked-by: Jason Wang +Message-Id: <20240410070459.49112-1-philmd@linaro.org> +--- + hw/net/net_tx_pkt.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/hw/net/net_tx_pkt.c b/hw/net/net_tx_pkt.c +index 2134a18c4c..b7b1de816d 100644 +--- a/hw/net/net_tx_pkt.c ++++ b/hw/net/net_tx_pkt.c +@@ -141,6 +141,10 @@ bool net_tx_pkt_update_sctp_checksum(struct NetTxPkt *pkt) + uint32_t csum = 0; + struct iovec *pl_start_frag = pkt->vec + NET_TX_PKT_PL_START_FRAG; + ++ if (iov_size(pl_start_frag, pkt->payload_frags) < 8 + sizeof(csum)) { ++ return false; ++ } ++ + if (iov_from_buf(pl_start_frag, pkt->payload_frags, 8, &csum, sizeof(csum)) < sizeof(csum)) { + return false; + } +-- +2.41.0 + diff --git a/CVE-2024-4467-0001-qcow2-Don-t-open-data_file-with-BDRV_O_NO_IO.patch b/CVE-2024-4467-0001-qcow2-Don-t-open-data_file-with-BDRV_O_NO_IO.patch new file mode 100644 index 0000000..d67965b --- /dev/null +++ b/CVE-2024-4467-0001-qcow2-Don-t-open-data_file-with-BDRV_O_NO_IO.patch @@ -0,0 +1,108 @@ +From bd385a5298d7062668e804d73944d52aec9549f1 Mon Sep 17 00:00:00 2001 +From: Kevin Wolf +Date: Thu, 11 Apr 2024 15:06:01 +0200 +Subject: [PATCH] qcow2: Don't open data_file with BDRV_O_NO_IO + +One use case for 'qemu-img info' is verifying that untrusted images +don't reference an unwanted external file, be it as a backing file or an +external data file. To make sure that calling 'qemu-img info' can't +already have undesired side effects with a malicious image, just don't +open the data file at all with BDRV_O_NO_IO. If nothing ever tries to do +I/O, we don't need to have it open. + +This changes the output of iotests case 061, which used 'qemu-img info' +to show that opening an image with an invalid data file fails. After +this patch, it succeeds. Replace this part of the test with a qemu-io +call, but keep the final 'qemu-img info' to show that the invalid data +file is correctly displayed in the output. + +Fixes: CVE-2024-4467 +Cc: qemu-stable@nongnu.org +Signed-off-by: Kevin Wolf +Reviewed-by: Eric Blake +Reviewed-by: Stefan Hajnoczi +Reviewed-by: Hanna Czenczek +--- + block/qcow2.c | 17 ++++++++++++++++- + tests/qemu-iotests/061 | 6 ++++-- + tests/qemu-iotests/061.out | 8 ++++++-- + 3 files changed, 26 insertions(+), 5 deletions(-) + +diff --git a/block/qcow2.c b/block/qcow2.c +index 10883a2494..70b19730a3 100644 +--- a/block/qcow2.c ++++ b/block/qcow2.c +@@ -1636,7 +1636,22 @@ qcow2_do_open(BlockDriverState *bs, QDict *options, int flags, + goto fail; + } + +- if (open_data_file) { ++ if (open_data_file && (flags & BDRV_O_NO_IO)) { ++ /* ++ * Don't open the data file for 'qemu-img info' so that it can be used ++ * to verify that an untrusted qcow2 image doesn't refer to external ++ * files. ++ * ++ * Note: This still makes has_data_file() return true. ++ */ ++ if (s->incompatible_features & QCOW2_INCOMPAT_DATA_FILE) { ++ s->data_file = NULL; ++ } else { ++ s->data_file = bs->file; ++ } ++ qdict_extract_subqdict(options, NULL, "data-file."); ++ qdict_del(options, "data-file"); ++ } else if (open_data_file) { + /* Open external data file */ + bdrv_graph_co_rdunlock(); + s->data_file = bdrv_co_open_child(NULL, options, "data-file", bs, +diff --git a/tests/qemu-iotests/061 b/tests/qemu-iotests/061 +index 53c7d428e3..b71ac097d1 100755 +--- a/tests/qemu-iotests/061 ++++ b/tests/qemu-iotests/061 +@@ -326,12 +326,14 @@ $QEMU_IMG amend -o "data_file=foo" "$TEST_IMG" + echo + _make_test_img -o "compat=1.1,data_file=$TEST_IMG.data" 64M + $QEMU_IMG amend -o "data_file=foo" "$TEST_IMG" +-_img_info --format-specific ++$QEMU_IO -c "read 0 4k" "$TEST_IMG" 2>&1 | _filter_testdir | _filter_imgfmt ++$QEMU_IO -c "open -o data-file.filename=$TEST_IMG.data,file.filename=$TEST_IMG" -c "read 0 4k" | _filter_qemu_io + TEST_IMG="data-file.filename=$TEST_IMG.data,file.filename=$TEST_IMG" _img_info --format-specific --image-opts + + echo + $QEMU_IMG amend -o "data_file=" --image-opts "data-file.filename=$TEST_IMG.data,file.filename=$TEST_IMG" +-_img_info --format-specific ++$QEMU_IO -c "read 0 4k" "$TEST_IMG" 2>&1 | _filter_testdir | _filter_imgfmt ++$QEMU_IO -c "open -o data-file.filename=$TEST_IMG.data,file.filename=$TEST_IMG" -c "read 0 4k" | _filter_qemu_io + TEST_IMG="data-file.filename=$TEST_IMG.data,file.filename=$TEST_IMG" _img_info --format-specific --image-opts + + echo +diff --git a/tests/qemu-iotests/061.out b/tests/qemu-iotests/061.out +index 139fc68177..24c33add7c 100644 +--- a/tests/qemu-iotests/061.out ++++ b/tests/qemu-iotests/061.out +@@ -545,7 +545,9 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 + qemu-img: data-file can only be set for images that use an external data file + + Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 data_file=TEST_DIR/t.IMGFMT.data +-qemu-img: Could not open 'TEST_DIR/t.IMGFMT': Could not open 'foo': No such file or directory ++qemu-io: can't open device TEST_DIR/t.IMGFMT: Could not open 'foo': No such file or directory ++read 4096/4096 bytes at offset 0 ++4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) + image: TEST_DIR/t.IMGFMT + file format: IMGFMT + virtual size: 64 MiB (67108864 bytes) +@@ -560,7 +562,9 @@ Format specific information: + corrupt: false + extended l2: false + +-qemu-img: Could not open 'TEST_DIR/t.IMGFMT': 'data-file' is required for this image ++qemu-io: can't open device TEST_DIR/t.IMGFMT: 'data-file' is required for this image ++read 4096/4096 bytes at offset 0 ++4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) + image: TEST_DIR/t.IMGFMT + file format: IMGFMT + virtual size: 64 MiB (67108864 bytes) +-- +2.41.0 + diff --git a/CVE-2024-4467-0002-iotests-244-Don-t-store-data-file-with-protocol-in-i.patch b/CVE-2024-4467-0002-iotests-244-Don-t-store-data-file-with-protocol-in-i.patch new file mode 100644 index 0000000..a0198da --- /dev/null +++ b/CVE-2024-4467-0002-iotests-244-Don-t-store-data-file-with-protocol-in-i.patch @@ -0,0 +1,51 @@ +From 2eb42a728d27a43fdcad5f37d3f65706ce6deba5 Mon Sep 17 00:00:00 2001 +From: Kevin Wolf +Date: Thu, 25 Apr 2024 14:49:40 +0200 +Subject: [PATCH] iotests/244: Don't store data-file with protocol in image + +We want to disable filename parsing for data files because it's too easy +to abuse in malicious image files. Make the test ready for the change by +passing the data file explicitly in command line options. + +Cc: qemu-stable@nongnu.org +Signed-off-by: Kevin Wolf +Reviewed-by: Eric Blake +Reviewed-by: Stefan Hajnoczi +Reviewed-by: Hanna Czenczek +--- + tests/qemu-iotests/244 | 19 ++++++++++++++++--- + 1 file changed, 16 insertions(+), 3 deletions(-) + +diff --git a/tests/qemu-iotests/244 b/tests/qemu-iotests/244 +index 3e61fa25bb..bb9cc6512f 100755 +--- a/tests/qemu-iotests/244 ++++ b/tests/qemu-iotests/244 +@@ -215,9 +215,22 @@ $QEMU_IMG convert -f $IMGFMT -O $IMGFMT -n -C "$TEST_IMG.src" "$TEST_IMG" + $QEMU_IMG compare -f $IMGFMT -F $IMGFMT "$TEST_IMG.src" "$TEST_IMG" + + # blkdebug doesn't support copy offloading, so this tests the error path +-$QEMU_IMG amend -f $IMGFMT -o "data_file=blkdebug::$TEST_IMG.data" "$TEST_IMG" +-$QEMU_IMG convert -f $IMGFMT -O $IMGFMT -n -C "$TEST_IMG.src" "$TEST_IMG" +-$QEMU_IMG compare -f $IMGFMT -F $IMGFMT "$TEST_IMG.src" "$TEST_IMG" ++test_img_with_blkdebug="json:{ ++ 'driver': 'qcow2', ++ 'file': { ++ 'driver': 'file', ++ 'filename': '$TEST_IMG' ++ }, ++ 'data-file': { ++ 'driver': 'blkdebug', ++ 'image': { ++ 'driver': 'file', ++ 'filename': '$TEST_IMG.data' ++ } ++ } ++}" ++$QEMU_IMG convert -f $IMGFMT -O $IMGFMT -n -C "$TEST_IMG.src" "$test_img_with_blkdebug" ++$QEMU_IMG compare -f $IMGFMT -F $IMGFMT "$TEST_IMG.src" "$test_img_with_blkdebug" + + echo + echo "=== Flushing should flush the data file ===" +-- +2.41.0 + diff --git a/CVE-2024-4467-0003-iotests-270-Don-t-store-data-file-with-json-prefix-i.patch b/CVE-2024-4467-0003-iotests-270-Don-t-store-data-file-with-json-prefix-i.patch new file mode 100644 index 0000000..8256e27 --- /dev/null +++ b/CVE-2024-4467-0003-iotests-270-Don-t-store-data-file-with-json-prefix-i.patch @@ -0,0 +1,53 @@ +From 7e1110664ecbc4826f3c978ccb06b6c1bce823e6 Mon Sep 17 00:00:00 2001 +From: Kevin Wolf +Date: Thu, 25 Apr 2024 14:49:40 +0200 +Subject: [PATCH] iotests/270: Don't store data-file with json: prefix in image + +We want to disable filename parsing for data files because it's too easy +to abuse in malicious image files. Make the test ready for the change by +passing the data file explicitly in command line options. + +Cc: qemu-stable@nongnu.org +Signed-off-by: Kevin Wolf +Reviewed-by: Eric Blake +Reviewed-by: Stefan Hajnoczi +Reviewed-by: Hanna Czenczek +--- + tests/qemu-iotests/270 | 14 +++++++++++--- + 1 file changed, 11 insertions(+), 3 deletions(-) + +diff --git a/tests/qemu-iotests/270 b/tests/qemu-iotests/270 +index 74352342db..c37b674aa2 100755 +--- a/tests/qemu-iotests/270 ++++ b/tests/qemu-iotests/270 +@@ -60,8 +60,16 @@ _make_test_img -o cluster_size=2M,data_file="$TEST_IMG.orig" \ + # "write" 2G of data without using any space. + # (qemu-img create does not like it, though, because null-co does not + # support image creation.) +-$QEMU_IMG amend -o data_file="json:{'driver':'null-co',,'size':'4294967296'}" \ +- "$TEST_IMG" ++test_img_with_null_data="json:{ ++ 'driver': '$IMGFMT', ++ 'file': { ++ 'filename': '$TEST_IMG' ++ }, ++ 'data-file': { ++ 'driver': 'null-co', ++ 'size':'4294967296' ++ } ++}" + + # This gives us a range of: + # 2^31 - 512 + 768 - 1 = 2^31 + 255 > 2^31 +@@ -74,7 +82,7 @@ $QEMU_IMG amend -o data_file="json:{'driver':'null-co',,'size':'4294967296'}" \ + # on L2 boundaries, we need large L2 tables; hence the cluster size of + # 2 MB. (Anything from 256 kB should work, though, because then one L2 + # table covers 8 GB.) +-$QEMU_IO -c "write 768 $((2 ** 31 - 512))" "$TEST_IMG" | _filter_qemu_io ++$QEMU_IO -c "write 768 $((2 ** 31 - 512))" "$test_img_with_null_data" | _filter_qemu_io + + _check_test_img + +-- +2.41.0 + diff --git a/CVE-2024-4467-0004-block-Parse-filenames-only-when-explicitly-requested.patch b/CVE-2024-4467-0004-block-Parse-filenames-only-when-explicitly-requested.patch new file mode 100644 index 0000000..cb5e419 --- /dev/null +++ b/CVE-2024-4467-0004-block-Parse-filenames-only-when-explicitly-requested.patch @@ -0,0 +1,247 @@ +From 7ead946998610657d38d1a505d5f25300d4ca613 Mon Sep 17 00:00:00 2001 +From: Kevin Wolf +Date: Thu, 25 Apr 2024 14:56:02 +0200 +Subject: [PATCH] block: Parse filenames only when explicitly requested + +When handling image filenames from legacy options such as -drive or from +tools, these filenames are parsed for protocol prefixes, including for +the json:{} pseudo-protocol. + +This behaviour is intended for filenames that come directly from the +command line and for backing files, which may come from the image file +itself. Higher level management tools generally take care to verify that +untrusted images don't contain a bad (or any) backing file reference; +'qemu-img info' is a suitable tool for this. + +However, for other files that can be referenced in images, such as +qcow2 data files or VMDK extents, the string from the image file is +usually not verified by management tools - and 'qemu-img info' wouldn't +be suitable because in contrast to backing files, it already opens these +other referenced files. So here the string should be interpreted as a +literal local filename. More complex configurations need to be specified +explicitly on the command line or in QMP. + +This patch changes bdrv_open_inherit() so that it only parses filenames +if a new parameter parse_filename is true. It is set for the top level +in bdrv_open(), for the file child and for the backing file child. All +other callers pass false and disable filename parsing this way. + +Cc: qemu-stable@nongnu.org +Signed-off-by: Kevin Wolf +Reviewed-by: Eric Blake +Reviewed-by: Stefan Hajnoczi +Reviewed-by: Hanna Czenczek +--- + block.c | 90 ++++++++++++++++++++++++++++++++++++--------------------- + 1 file changed, 57 insertions(+), 33 deletions(-) + +diff --git a/block.c b/block.c +index bfb0861ec..86c20c27d 100644 +--- a/block.c ++++ b/block.c +@@ -86,6 +86,7 @@ static BlockDriverState *bdrv_open_inherit(const char *filename, + BlockDriverState *parent, + const BdrvChildClass *child_class, + BdrvChildRole child_role, ++ bool parse_filename, + Error **errp); + + static bool bdrv_recurse_has_child(BlockDriverState *bs, +@@ -2047,7 +2048,8 @@ static void parse_json_protocol(QDict *options, const char **pfilename, + * block driver has been specified explicitly. + */ + static int bdrv_fill_options(QDict **options, const char *filename, +- int *flags, Error **errp) ++ int *flags, bool allow_parse_filename, ++ Error **errp) + { + const char *drvname; + bool protocol = *flags & BDRV_O_PROTOCOL; +@@ -2089,7 +2091,7 @@ static int bdrv_fill_options(QDict **options, const char *filename, + if (protocol && filename) { + if (!qdict_haskey(*options, "filename")) { + qdict_put_str(*options, "filename", filename); +- parse_filename = true; ++ parse_filename = allow_parse_filename; + } else { + error_setg(errp, "Can't specify 'file' and 'filename' options at " + "the same time"); +@@ -3675,7 +3677,8 @@ int bdrv_open_backing_file(BlockDriverState *bs, QDict *parent_options, + } + + backing_hd = bdrv_open_inherit(backing_filename, reference, options, 0, bs, +- &child_of_bds, bdrv_backing_role(bs), errp); ++ &child_of_bds, bdrv_backing_role(bs), true, ++ errp); + if (!backing_hd) { + bs->open_flags |= BDRV_O_NO_BACKING; + error_prepend(errp, "Could not open backing file: "); +@@ -3712,7 +3715,8 @@ free_exit: + static BlockDriverState * + bdrv_open_child_bs(const char *filename, QDict *options, const char *bdref_key, + BlockDriverState *parent, const BdrvChildClass *child_class, +- BdrvChildRole child_role, bool allow_none, Error **errp) ++ BdrvChildRole child_role, bool allow_none, ++ bool parse_filename, Error **errp) + { + BlockDriverState *bs = NULL; + QDict *image_options; +@@ -3743,7 +3747,8 @@ bdrv_open_child_bs(const char *filename, QDict *options, const char *bdref_key, + } + + bs = bdrv_open_inherit(filename, reference, image_options, 0, +- parent, child_class, child_role, errp); ++ parent, child_class, child_role, parse_filename, ++ errp); + if (!bs) { + goto done; + } +@@ -3753,6 +3758,37 @@ done: + return bs; + } + ++static BdrvChild *bdrv_open_child_common(const char *filename, ++ QDict *options, const char *bdref_key, ++ BlockDriverState *parent, ++ const BdrvChildClass *child_class, ++ BdrvChildRole child_role, ++ bool allow_none, bool parse_filename, ++ Error **errp) ++{ ++ BlockDriverState *bs; ++ BdrvChild *child; ++ AioContext *ctx; ++ ++ GLOBAL_STATE_CODE(); ++ ++ bs = bdrv_open_child_bs(filename, options, bdref_key, parent, child_class, ++ child_role, allow_none, parse_filename, errp); ++ if (bs == NULL) { ++ return NULL; ++ } ++ ++ bdrv_graph_wrlock(NULL); ++ ctx = bdrv_get_aio_context(bs); ++ aio_context_acquire(ctx); ++ child = bdrv_attach_child(parent, bs, bdref_key, child_class, child_role, ++ errp); ++ aio_context_release(ctx); ++ bdrv_graph_wrunlock(NULL); ++ ++ return child; ++} ++ + /* + * Opens a disk image whose options are given as BlockdevRef in another block + * device's options. +@@ -3778,31 +3814,15 @@ BdrvChild *bdrv_open_child(const char *filename, + BdrvChildRole child_role, + bool allow_none, Error **errp) + { +- BlockDriverState *bs; +- BdrvChild *child; +- AioContext *ctx; +- +- GLOBAL_STATE_CODE(); +- +- bs = bdrv_open_child_bs(filename, options, bdref_key, parent, child_class, +- child_role, allow_none, errp); +- if (bs == NULL) { +- return NULL; +- } +- +- bdrv_graph_wrlock(NULL); +- ctx = bdrv_get_aio_context(bs); +- aio_context_acquire(ctx); +- child = bdrv_attach_child(parent, bs, bdref_key, child_class, child_role, +- errp); +- aio_context_release(ctx); +- bdrv_graph_wrunlock(NULL); +- +- return child; ++ return bdrv_open_child_common(filename, options, bdref_key, parent, ++ child_class, child_role, allow_none, false, ++ errp); + } + + /* +- * Wrapper on bdrv_open_child() for most popular case: open primary child of bs. ++ * This does mostly the same as bdrv_open_child(), but for opening the primary ++ * child of a node. A notable difference from bdrv_open_child() is that it ++ * enables filename parsing for protocol names (including json:). + * + * The caller must hold the lock of the main AioContext and no other AioContext. + * @parent can move to a different AioContext in this function. Callers must +@@ -3819,8 +3839,8 @@ int bdrv_open_file_child(const char *filename, + role = parent->drv->is_filter ? + (BDRV_CHILD_FILTERED | BDRV_CHILD_PRIMARY) : BDRV_CHILD_IMAGE; + +- if (!bdrv_open_child(filename, options, bdref_key, parent, +- &child_of_bds, role, false, errp)) ++ if (!bdrv_open_child_common(filename, options, bdref_key, parent, ++ &child_of_bds, role, false, true, errp)) + { + return -EINVAL; + } +@@ -3865,7 +3885,8 @@ BlockDriverState *bdrv_open_blockdev_ref(BlockdevRef *ref, Error **errp) + + } + +- bs = bdrv_open_inherit(NULL, reference, qdict, 0, NULL, NULL, 0, errp); ++ bs = bdrv_open_inherit(NULL, reference, qdict, 0, NULL, NULL, 0, false, ++ errp); + obj = NULL; + qobject_unref(obj); + visit_free(v); +@@ -3962,7 +3983,7 @@ static BlockDriverState * no_coroutine_fn + bdrv_open_inherit(const char *filename, const char *reference, QDict *options, + int flags, BlockDriverState *parent, + const BdrvChildClass *child_class, BdrvChildRole child_role, +- Error **errp) ++ bool parse_filename, Error **errp) + { + int ret; + BlockBackend *file = NULL; +@@ -4011,9 +4032,11 @@ bdrv_open_inherit(const char *filename, const char *reference, QDict *options, + } + + /* json: syntax counts as explicit options, as if in the QDict */ +- parse_json_protocol(options, &filename, &local_err); +- if (local_err) { +- goto fail; ++ if (parse_filename) { ++ parse_json_protocol(options, &filename, &local_err); ++ if (local_err) { ++ goto fail; ++ } + } + + bs->explicit_options = qdict_clone_shallow(options); +@@ -4038,7 +4061,8 @@ bdrv_open_inherit(const char *filename, const char *reference, QDict *options, + parent->open_flags, parent->options); + } + +- ret = bdrv_fill_options(&options, filename, &flags, &local_err); ++ ret = bdrv_fill_options(&options, filename, &flags, parse_filename, ++ &local_err); + if (ret < 0) { + goto fail; + } +@@ -4107,7 +4131,7 @@ bdrv_open_inherit(const char *filename, const char *reference, QDict *options, + + file_bs = bdrv_open_child_bs(filename, options, "file", bs, + &child_of_bds, BDRV_CHILD_IMAGE, +- true, &local_err); ++ true, true, &local_err); + if (local_err) { + goto fail; + } +@@ -4270,7 +4294,7 @@ BlockDriverState *bdrv_open(const char *filename, const char *reference, + GLOBAL_STATE_CODE(); + + return bdrv_open_inherit(filename, reference, options, flags, NULL, +- NULL, 0, errp); ++ NULL, 0, true, errp); + } + + /* Return true if the NULL-terminated @list contains @str */ diff --git a/CVE-2024-6505-virtio-net-Ensure-queue-index-fits-with-RSS.patch b/CVE-2024-6505-virtio-net-Ensure-queue-index-fits-with-RSS.patch new file mode 100644 index 0000000..149ef99 --- /dev/null +++ b/CVE-2024-6505-virtio-net-Ensure-queue-index-fits-with-RSS.patch @@ -0,0 +1,33 @@ +From f1595ceb9aad36a6c1da95bcb77ab9509b38822d Mon Sep 17 00:00:00 2001 +From: Akihiko Odaki +Date: Mon, 1 Jul 2024 20:58:04 +0900 +Subject: [PATCH] virtio-net: Ensure queue index fits with RSS + +Ensure the queue index points to a valid queue when software RSS +enabled. The new calculation matches with the behavior of Linux's TAP +device with the RSS eBPF program. + +Fixes: 4474e37a5b3a ("virtio-net: implement RX RSS processing") +Reported-by: Zhibin Hu +Cc: qemu-stable@nongnu.org +Signed-off-by: Akihiko Odaki +Reviewed-by: Michael S. Tsirkin +Signed-off-by: Jason Wang +--- + hw/net/virtio-net.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c +index 73024babd..08b69e8e5 100644 +--- a/hw/net/virtio-net.c ++++ b/hw/net/virtio-net.c +@@ -1909,7 +1909,8 @@ static ssize_t virtio_net_receive_rcu(NetClientState *nc, const uint8_t *buf, + if (!no_rss && n->rss_data.enabled && n->rss_data.enabled_software_rss) { + int index = virtio_net_process_rss(nc, buf, size); + if (index >= 0) { +- NetClientState *nc2 = qemu_get_subqueue(n->nic, index); ++ NetClientState *nc2 = ++ qemu_get_subqueue(n->nic, index % n->curr_queue_pairs); + return virtio_net_receive_rcu(nc2, buf, size, true); + } + } diff --git a/CVE-2024-7730-virtio-snd-add-max-size-bounds-check-in-input-cb.patch b/CVE-2024-7730-virtio-snd-add-max-size-bounds-check-in-input-cb.patch new file mode 100644 index 0000000..20b5f52 --- /dev/null +++ b/CVE-2024-7730-virtio-snd-add-max-size-bounds-check-in-input-cb.patch @@ -0,0 +1,58 @@ +From 98e77e3dd8dd6e7aa9a7dffa60f49c8c8a49d4e3 Mon Sep 17 00:00:00 2001 +From: Manos Pitsidianakis +Date: Mon, 8 Jul 2024 10:09:49 +0300 +Subject: [PATCH] virtio-snd: add max size bounds check in input cb +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +When reading input audio in the virtio-snd input callback, +virtio_snd_pcm_in_cb(), we do not check whether the iov can actually fit +the data buffer. This is because we use the buffer->size field as a +total-so-far accumulator instead of byte-size-left like in TX buffers. + +This triggers an out of bounds write if the size of the virtio queue +element is equal to virtio_snd_pcm_status, which makes the available +space for audio data zero. This commit adds a check for reaching the +maximum buffer size before attempting any writes. + +Reported-by: Zheyu Ma +Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2427 +Signed-off-by: Manos Pitsidianakis +Message-Id: +Reviewed-by: Philippe Mathieu-Daudé +Reviewed-by: Michael S. Tsirkin +Signed-off-by: Michael S. Tsirkin +--- + hw/audio/virtio-snd.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +diff --git a/hw/audio/virtio-snd.c b/hw/audio/virtio-snd.c +index 5993f4f040..e6432ac959 100644 +--- a/hw/audio/virtio-snd.c ++++ b/hw/audio/virtio-snd.c +@@ -1261,7 +1261,7 @@ static void virtio_snd_pcm_in_cb(void *data, int available) + { + VirtIOSoundPCMStream *stream = data; + VirtIOSoundPCMBuffer *buffer; +- size_t size; ++ size_t size, max_size; + + WITH_QEMU_LOCK_GUARD(&stream->queue_mutex) { + while (!QSIMPLEQ_EMPTY(&stream->queue)) { +@@ -1275,7 +1275,12 @@ static void virtio_snd_pcm_in_cb(void *data, int available) + continue; + } + ++ max_size = iov_size(buffer->elem->in_sg, buffer->elem->in_num); + for (;;) { ++ if (buffer->size >= max_size) { ++ return_rx_buffer(stream, buffer); ++ break; ++ } + size = AUD_read(stream->voice.in, + buffer->data + buffer->size, + MIN(available, (stream->params.period_bytes - +-- +2.41.0 + diff --git a/qemu.spec b/qemu.spec index e7b7365..cf55e0a 100644 --- a/qemu.spec +++ b/qemu.spec @@ -136,7 +136,7 @@ Summary: QEMU is a FAST! processor emulator Name: qemu Version: 8.2.2 -Release: 12%{?dist} +Release: 13%{?dist} License: GPLv2 and BSD and MIT and CC-BY URL: http://www.qemu.org/ Source0: http://wiki.qemu-project.org/download/%{name}-%{version}.tar.xz @@ -259,6 +259,18 @@ Patch0101: nbd-server-CVE-2024-7409-Drop-non-negotiating-client.patch Patch0102: nbd-server-CVE-2024-7409-Close-stray-clients-at-serv.patch Patch0103: nbd-server-CVE-2024-7409-Avoid-use-after-free-when-c.patch +#CVE-2024-3567 +Patch0104: CVE-2024-3567-hw-net-net_tx_pkt-Fix-overrun-in-update_sctp_checksu.patch +#CVE-2024-4467 +Patch0105: CVE-2024-4467-0001-qcow2-Don-t-open-data_file-with-BDRV_O_NO_IO.patch +Patch0106: CVE-2024-4467-0002-iotests-244-Don-t-store-data-file-with-protocol-in-i.patch +Patch0107: CVE-2024-4467-0003-iotests-270-Don-t-store-data-file-with-json-prefix-i.patch +Patch0108: CVE-2024-4467-0004-block-Parse-filenames-only-when-explicitly-requested.patch +#CVE-2024-6505 +Patch0109: CVE-2024-6505-virtio-net-Ensure-queue-index-fits-with-RSS.patch +#CVE-2024-7730 +Patch0110: CVE-2024-7730-virtio-snd-add-max-size-bounds-check-in-input-cb.patch + BuildRequires: meson >= %{meson_version} BuildRequires: zlib-devel BuildRequires: glib2-devel @@ -1993,6 +2005,15 @@ useradd -r -u 107 -g qemu -G kvm -d / -s /sbin/nologin \ %changelog +* Sat Sep 21 2024 Chunsheng Luo - 8.2.2-13 +- hw/net/net_tx_pkt: Fix overrun in update_sctp_checksum()(CVE-2024-3567) +- qcow2: Don't open data_file with BDRV_O_NO_IO(CVE-2024-4467) +- iotests/244: Don't store data-file with protocol in image(CVE-2024-4467) +- iotests/270: Don't store data-file with json: prefix in image(CVE-2024-4467) +- block: Parse filenames only when explicitly requested(CVE-2024-4467) +- virtio-net: Ensure queue index fits with RSS(CVE-2024-6505) +- virtio-snd: add max size bounds check in input cb(CVE-2024-7730) + * Mon Sep 9 2024 Chunsheng Luo - 8.2.2-12 - nbd/server: CVE-2024-7409: Avoid use-after-free when closing server - nbd/server: CVE-2024-7409: Close stray clients at server-stop -- Gitee