summaryrefslogtreecommitdiffstats
path: root/meta
diff options
context:
space:
mode:
authorVijay Anusuri <vanusuri@mvista.com>2024-09-06 14:56:27 +0530
committerSteve Sakoman <steve@sakoman.com>2024-09-16 06:09:56 -0700
commitd0429def9e227ef70e97739c33387c88a70b2bde (patch)
treed3b912a98d4880e8ecf7d271c5644f66c57d14b7 /meta
parentbfbf6d481d4d9d21fd624528c8a61ccc64fadc4c (diff)
downloadpoky-d0429def9e227ef70e97739c33387c88a70b2bde.tar.gz
qemu: Backport fix for CVE-2024-4467
A flaw was found in the QEMU disk image utility (qemu-img) 'info' command. A specially crafted image file containing a `json:{}` value describing block devices in QMP could cause the qemu-img process on the host to consume large amounts of memory or CPU time, leading to denial of service or read/write to an existing external file. Reference: https://nvd.nist.gov/vuln/detail/CVE-2024-4467 Upstream commits: https://gitlab.com/qemu-project/qemu/-/commit/bd385a5298d7062668e804d73944d52aec9549f1 https://gitlab.com/qemu-project/qemu/-/commit/2eb42a728d27a43fdcad5f37d3f65706ce6deba5 https://gitlab.com/qemu-project/qemu/-/commit/7e1110664ecbc4826f3c978ccb06b6c1bce823e6 https://gitlab.com/qemu-project/qemu/-/commit/83930780325b144a5908c45b3957b9b6457b3831 https://gitlab.com/qemu-project/qemu/-/commit/7ead946998610657d38d1a505d5f25300d4ca613 (From OE-Core rev: c23ad8c89c3dd5b6004677cd0b534e22a293134d) Signed-off-by: Vijay Anusuri <vanusuri@mvista.com> Signed-off-by: Steve Sakoman <steve@sakoman.com>
Diffstat (limited to 'meta')
-rw-r--r--meta/recipes-devtools/qemu/qemu.inc5
-rw-r--r--meta/recipes-devtools/qemu/qemu/CVE-2024-4467-0001.patch214
-rw-r--r--meta/recipes-devtools/qemu/qemu/CVE-2024-4467-0002.patch73
-rw-r--r--meta/recipes-devtools/qemu/qemu/CVE-2024-4467-0003.patch76
-rw-r--r--meta/recipes-devtools/qemu/qemu/CVE-2024-4467-0004.patch571
-rw-r--r--meta/recipes-devtools/qemu/qemu/CVE-2024-4467-0005.patch265
6 files changed, 1204 insertions, 0 deletions
diff --git a/meta/recipes-devtools/qemu/qemu.inc b/meta/recipes-devtools/qemu/qemu.inc
index 4684e44524..6ff3c2f9bc 100644
--- a/meta/recipes-devtools/qemu/qemu.inc
+++ b/meta/recipes-devtools/qemu/qemu.inc
@@ -113,6 +113,11 @@ SRC_URI = "https://download.qemu.org/${BPN}-${PV}.tar.xz \
113 file://CVE-2024-7409-0002.patch \ 113 file://CVE-2024-7409-0002.patch \
114 file://CVE-2024-7409-0003.patch \ 114 file://CVE-2024-7409-0003.patch \
115 file://CVE-2024-7409-0004.patch \ 115 file://CVE-2024-7409-0004.patch \
116 file://CVE-2024-4467-0001.patch \
117 file://CVE-2024-4467-0002.patch \
118 file://CVE-2024-4467-0003.patch \
119 file://CVE-2024-4467-0004.patch \
120 file://CVE-2024-4467-0005.patch \
116 " 121 "
117UPSTREAM_CHECK_REGEX = "qemu-(?P<pver>\d+(\.\d+)+)\.tar" 122UPSTREAM_CHECK_REGEX = "qemu-(?P<pver>\d+(\.\d+)+)\.tar"
118 123
diff --git a/meta/recipes-devtools/qemu/qemu/CVE-2024-4467-0001.patch b/meta/recipes-devtools/qemu/qemu/CVE-2024-4467-0001.patch
new file mode 100644
index 0000000000..f7c6e7aaab
--- /dev/null
+++ b/meta/recipes-devtools/qemu/qemu/CVE-2024-4467-0001.patch
@@ -0,0 +1,214 @@
1From 5cdbc87ab24a8cc4cf926158ec429d43d8a45f15 Mon Sep 17 00:00:00 2001
2From: Jon Maloy <jmaloy@redhat.com>
3Date: Wed, 5 Jun 2024 19:56:51 -0400
4Subject: [PATCH 1/5] qcow2: Don't open data_file with BDRV_O_NO_IO
5MIME-Version: 1.0
6Content-Type: text/plain; charset=UTF-8
7Content-Transfer-Encoding: 8bit
8
9RH-Author: Jon Maloy <jmaloy@redhat.com>
10RH-MergeRequest: 5: EMBARGOED CVE-2024-4467 for rhel-8.10.z (PRDSC)
11RH-Jira: RHEL-35616
12RH-CVE: CVE-2024-4467
13RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
14RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
15RH-Commit: [1/5] 2e72d21c14d86645cf68eec78f49d5cc5d77581f
16
17Conflicts: qcow2_do_open(): missing boolean ´open_data_file'.
18 We assume it to be true.
19
20commit f9843ce5c519901654a7d8ba43ee95ce25ca13c2
21Author: Kevin Wolf <kwolf@redhat.com>
22Date: Thu Apr 11 15:06:01 2024 +0200
23
24 qcow2: Don't open data_file with BDRV_O_NO_IO
25
26 One use case for 'qemu-img info' is verifying that untrusted images
27 don't reference an unwanted external file, be it as a backing file or an
28 external data file. To make sure that calling 'qemu-img info' can't
29 already have undesired side effects with a malicious image, just don't
30 open the data file at all with BDRV_O_NO_IO. If nothing ever tries to do
31 I/O, we don't need to have it open.
32
33 This changes the output of iotests case 061, which used 'qemu-img info'
34 to show that opening an image with an invalid data file fails. After
35 this patch, it succeeds. Replace this part of the test with a qemu-io
36 call, but keep the final 'qemu-img info' to show that the invalid data
37 file is correctly displayed in the output.
38
39 Signed-off-by: Kevin Wolf <kwolf@redhat.com>
40 Reviewed-by: Eric Blake <eblake@redhat.com>
41 Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
42 Reviewed-by: Hanna Czenczek <hreitz@redhat.com>
43 Upstream: N/A, embargoed
44 Signed-off-by: Hanna Czenczek <hreitz@redhat.com>
45
46Signed-off-by: Jon Maloy <jmaloy@redhat.com>
47
48Upstream-Status: Backport [import from rhel8 qemu-kvm-6.2.0-50.module+el8.10.0+22027+db0a70a4.src.rpm
49Upstream commit https://gitlab.com/qemu-project/qemu/-/commit/bd385a5298d7062668e804d73944d52aec9549f1]
50CVE: CVE-2024-4467
51Signed-off-by: Vijay Anusuri <vanusuri@mvista.com>
52---
53 block/qcow2.c | 87 +++++++++++++++++++++++---------------
54 tests/qemu-iotests/061 | 6 ++-
55 tests/qemu-iotests/061.out | 8 +++-
56 3 files changed, 62 insertions(+), 39 deletions(-)
57
58diff --git a/block/qcow2.c b/block/qcow2.c
59index d509016756..6ee1919612 100644
60--- a/block/qcow2.c
61+++ b/block/qcow2.c
62@@ -1613,50 +1613,67 @@ static int coroutine_fn qcow2_do_open(BlockDriverState *bs, QDict *options,
63 goto fail;
64 }
65
66- /* Open external data file */
67- s->data_file = bdrv_open_child(NULL, options, "data-file", bs,
68- &child_of_bds, BDRV_CHILD_DATA,
69- true, errp);
70- if (*errp) {
71- ret = -EINVAL;
72- goto fail;
73- }
74+ if (flags & BDRV_O_NO_IO) {
75+ /*
76+ * Don't open the data file for 'qemu-img info' so that it can be used
77+ * to verify that an untrusted qcow2 image doesn't refer to external
78+ * files.
79+ *
80+ * Note: This still makes has_data_file() return true.
81+ */
82+ if (s->incompatible_features & QCOW2_INCOMPAT_DATA_FILE) {
83+ s->data_file = NULL;
84+ } else {
85+ s->data_file = bs->file;
86+ }
87+ qdict_extract_subqdict(options, NULL, "data-file.");
88+ qdict_del(options, "data-file");
89+ } else {
90+ /* Open external data file */
91+ s->data_file = bdrv_open_child(NULL, options, "data-file", bs,
92+ &child_of_bds, BDRV_CHILD_DATA,
93+ true, errp);
94+ if (*errp) {
95+ ret = -EINVAL;
96+ goto fail;
97+ }
98
99- if (s->incompatible_features & QCOW2_INCOMPAT_DATA_FILE) {
100- if (!s->data_file && s->image_data_file) {
101- s->data_file = bdrv_open_child(s->image_data_file, options,
102- "data-file", bs, &child_of_bds,
103- BDRV_CHILD_DATA, false, errp);
104+ if (s->incompatible_features & QCOW2_INCOMPAT_DATA_FILE) {
105+ if (!s->data_file && s->image_data_file) {
106+ s->data_file = bdrv_open_child(s->image_data_file, options,
107+ "data-file", bs, &child_of_bds,
108+ BDRV_CHILD_DATA, false, errp);
109+ if (!s->data_file) {
110+ ret = -EINVAL;
111+ goto fail;
112+ }
113+ }
114 if (!s->data_file) {
115+ error_setg(errp, "'data-file' is required for this image");
116 ret = -EINVAL;
117 goto fail;
118 }
119- }
120- if (!s->data_file) {
121- error_setg(errp, "'data-file' is required for this image");
122- ret = -EINVAL;
123- goto fail;
124- }
125
126- /* No data here */
127- bs->file->role &= ~BDRV_CHILD_DATA;
128+ /* No data here */
129+ bs->file->role &= ~BDRV_CHILD_DATA;
130
131- /* Must succeed because we have given up permissions if anything */
132- bdrv_child_refresh_perms(bs, bs->file, &error_abort);
133- } else {
134- if (s->data_file) {
135- error_setg(errp, "'data-file' can only be set for images with an "
136- "external data file");
137- ret = -EINVAL;
138- goto fail;
139- }
140+ /* Must succeed because we have given up permissions if anything */
141+ bdrv_child_refresh_perms(bs, bs->file, &error_abort);
142+ } else {
143+ if (s->data_file) {
144+ error_setg(errp, "'data-file' can only be set for images with an "
145+ "external data file");
146+ ret = -EINVAL;
147+ goto fail;
148+ }
149
150- s->data_file = bs->file;
151+ s->data_file = bs->file;
152
153- if (data_file_is_raw(bs)) {
154- error_setg(errp, "data-file-raw requires a data file");
155- ret = -EINVAL;
156- goto fail;
157+ if (data_file_is_raw(bs)) {
158+ error_setg(errp, "data-file-raw requires a data file");
159+ ret = -EINVAL;
160+ goto fail;
161+ }
162 }
163 }
164
165diff --git a/tests/qemu-iotests/061 b/tests/qemu-iotests/061
166index 9507c223bd..6a5bd47efc 100755
167--- a/tests/qemu-iotests/061
168+++ b/tests/qemu-iotests/061
169@@ -322,12 +322,14 @@ $QEMU_IMG amend -o "data_file=foo" "$TEST_IMG"
170 echo
171 _make_test_img -o "compat=1.1,data_file=$TEST_IMG.data" 64M
172 $QEMU_IMG amend -o "data_file=foo" "$TEST_IMG"
173-_img_info --format-specific
174+$QEMU_IO -c "read 0 4k" "$TEST_IMG" 2>&1 | _filter_testdir | _filter_imgfmt
175+$QEMU_IO -c "open -o data-file.filename=$TEST_IMG.data,file.filename=$TEST_IMG" -c "read 0 4k" | _filter_qemu_io
176 TEST_IMG="data-file.filename=$TEST_IMG.data,file.filename=$TEST_IMG" _img_info --format-specific --image-opts
177
178 echo
179 $QEMU_IMG amend -o "data_file=" --image-opts "data-file.filename=$TEST_IMG.data,file.filename=$TEST_IMG"
180-_img_info --format-specific
181+$QEMU_IO -c "read 0 4k" "$TEST_IMG" 2>&1 | _filter_testdir | _filter_imgfmt
182+$QEMU_IO -c "open -o data-file.filename=$TEST_IMG.data,file.filename=$TEST_IMG" -c "read 0 4k" | _filter_qemu_io
183 TEST_IMG="data-file.filename=$TEST_IMG.data,file.filename=$TEST_IMG" _img_info --format-specific --image-opts
184
185 echo
186diff --git a/tests/qemu-iotests/061.out b/tests/qemu-iotests/061.out
187index 7ecbd4dea8..99b2307a23 100644
188--- a/tests/qemu-iotests/061.out
189+++ b/tests/qemu-iotests/061.out
190@@ -545,7 +545,9 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
191 qemu-img: data-file can only be set for images that use an external data file
192
193 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 data_file=TEST_DIR/t.IMGFMT.data
194-qemu-img: Could not open 'TEST_DIR/t.IMGFMT': Could not open 'foo': No such file or directory
195+qemu-io: can't open device TEST_DIR/t.IMGFMT: Could not open 'foo': No such file or directory
196+read 4096/4096 bytes at offset 0
197+4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
198 image: TEST_DIR/t.IMGFMT
199 file format: IMGFMT
200 virtual size: 64 MiB (67108864 bytes)
201@@ -560,7 +562,9 @@ Format specific information:
202 corrupt: false
203 extended l2: false
204
205-qemu-img: Could not open 'TEST_DIR/t.IMGFMT': 'data-file' is required for this image
206+qemu-io: can't open device TEST_DIR/t.IMGFMT: 'data-file' is required for this image
207+read 4096/4096 bytes at offset 0
208+4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
209 image: TEST_DIR/t.IMGFMT
210 file format: IMGFMT
211 virtual size: 64 MiB (67108864 bytes)
212--
2132.39.3
214
diff --git a/meta/recipes-devtools/qemu/qemu/CVE-2024-4467-0002.patch b/meta/recipes-devtools/qemu/qemu/CVE-2024-4467-0002.patch
new file mode 100644
index 0000000000..901ca7036d
--- /dev/null
+++ b/meta/recipes-devtools/qemu/qemu/CVE-2024-4467-0002.patch
@@ -0,0 +1,73 @@
1From 3cb587f460ec432f329fb83df034bbb7e79e17aa Mon Sep 17 00:00:00 2001
2From: Jon Maloy <jmaloy@redhat.com>
3Date: Wed, 5 Jun 2024 19:56:51 -0400
4Subject: [PATCH 2/5] iotests/244: Don't store data-file with protocol in image
5
6RH-Author: Jon Maloy <jmaloy@redhat.com>
7RH-MergeRequest: 5: EMBARGOED CVE-2024-4467 for rhel-8.10.z (PRDSC)
8RH-Jira: RHEL-35616
9RH-CVE: CVE-2024-4467
10RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
11RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
12RH-Commit: [2/5] a422cfdba938e1bd857008ccbbddc695011ae0ff
13
14commit 92e00dab8be1570b13172353d77d2af44cb4e22b
15Author: Kevin Wolf <kwolf@redhat.com>
16Date: Thu Apr 25 14:49:40 2024 +0200
17
18 iotests/244: Don't store data-file with protocol in image
19
20 We want to disable filename parsing for data files because it's too easy
21 to abuse in malicious image files. Make the test ready for the change by
22 passing the data file explicitly in command line options.
23
24 Signed-off-by: Kevin Wolf <kwolf@redhat.com>
25 Reviewed-by: Eric Blake <eblake@redhat.com>
26 Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
27 Reviewed-by: Hanna Czenczek <hreitz@redhat.com>
28 Upstream: N/A, embargoed
29 Signed-off-by: Hanna Czenczek <hreitz@redhat.com>
30
31Signed-off-by: Jon Maloy <jmaloy@redhat.com>
32
33Upstream-Status: Backport [import from rhel8 qemu-kvm-6.2.0-50.module+el8.10.0+22027+db0a70a4.src.rpm
34Upstream commit https://gitlab.com/qemu-project/qemu/-/commit/2eb42a728d27a43fdcad5f37d3f65706ce6deba5]
35CVE: CVE-2024-4467
36Signed-off-by: Vijay Anusuri <vanusuri@mvista.com>
37---
38 tests/qemu-iotests/244 | 19 ++++++++++++++++---
39 1 file changed, 16 insertions(+), 3 deletions(-)
40
41diff --git a/tests/qemu-iotests/244 b/tests/qemu-iotests/244
42index 3e61fa25bb..bb9cc6512f 100755
43--- a/tests/qemu-iotests/244
44+++ b/tests/qemu-iotests/244
45@@ -215,9 +215,22 @@ $QEMU_IMG convert -f $IMGFMT -O $IMGFMT -n -C "$TEST_IMG.src" "$TEST_IMG"
46 $QEMU_IMG compare -f $IMGFMT -F $IMGFMT "$TEST_IMG.src" "$TEST_IMG"
47
48 # blkdebug doesn't support copy offloading, so this tests the error path
49-$QEMU_IMG amend -f $IMGFMT -o "data_file=blkdebug::$TEST_IMG.data" "$TEST_IMG"
50-$QEMU_IMG convert -f $IMGFMT -O $IMGFMT -n -C "$TEST_IMG.src" "$TEST_IMG"
51-$QEMU_IMG compare -f $IMGFMT -F $IMGFMT "$TEST_IMG.src" "$TEST_IMG"
52+test_img_with_blkdebug="json:{
53+ 'driver': 'qcow2',
54+ 'file': {
55+ 'driver': 'file',
56+ 'filename': '$TEST_IMG'
57+ },
58+ 'data-file': {
59+ 'driver': 'blkdebug',
60+ 'image': {
61+ 'driver': 'file',
62+ 'filename': '$TEST_IMG.data'
63+ }
64+ }
65+}"
66+$QEMU_IMG convert -f $IMGFMT -O $IMGFMT -n -C "$TEST_IMG.src" "$test_img_with_blkdebug"
67+$QEMU_IMG compare -f $IMGFMT -F $IMGFMT "$TEST_IMG.src" "$test_img_with_blkdebug"
68
69 echo
70 echo "=== Flushing should flush the data file ==="
71--
722.39.3
73
diff --git a/meta/recipes-devtools/qemu/qemu/CVE-2024-4467-0003.patch b/meta/recipes-devtools/qemu/qemu/CVE-2024-4467-0003.patch
new file mode 100644
index 0000000000..89b4bbea5b
--- /dev/null
+++ b/meta/recipes-devtools/qemu/qemu/CVE-2024-4467-0003.patch
@@ -0,0 +1,76 @@
1From 59a84673079f9763e9507733e308442397aba703 Mon Sep 17 00:00:00 2001
2From: Jon Maloy <jmaloy@redhat.com>
3Date: Wed, 5 Jun 2024 19:56:51 -0400
4Subject: [PATCH 3/5] iotests/270: Don't store data-file with json: prefix in
5 image
6
7RH-Author: Jon Maloy <jmaloy@redhat.com>
8RH-MergeRequest: 5: EMBARGOED CVE-2024-4467 for rhel-8.10.z (PRDSC)
9RH-Jira: RHEL-35616
10RH-CVE: CVE-2024-4467
11RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
12RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
13RH-Commit: [3/5] ac08690fd3ea3af6e24b2f6a8beedcfe469917a8
14
15commit 705bcc2819ce8e0f8b9d660a93bc48de26413aec
16Author: Kevin Wolf <kwolf@redhat.com>
17Date: Thu Apr 25 14:49:40 2024 +0200
18
19 iotests/270: Don't store data-file with json: prefix in image
20
21 We want to disable filename parsing for data files because it's too easy
22 to abuse in malicious image files. Make the test ready for the change by
23 passing the data file explicitly in command line options.
24
25 Signed-off-by: Kevin Wolf <kwolf@redhat.com>
26 Reviewed-by: Eric Blake <eblake@redhat.com>
27 Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
28 Reviewed-by: Hanna Czenczek <hreitz@redhat.com>
29 Upstream: N/A, embargoed
30 Signed-off-by: Hanna Czenczek <hreitz@redhat.com>
31
32Signed-off-by: Jon Maloy <jmaloy@redhat.com>
33
34Upstream-Status: Backport [import from rhel8 qemu-kvm-6.2.0-50.module+el8.10.0+22027+db0a70a4.src.rpm
35Upstream commit https://gitlab.com/qemu-project/qemu/-/commit/7e1110664ecbc4826f3c978ccb06b6c1bce823e6]
36CVE: CVE-2024-4467
37Signed-off-by: Vijay Anusuri <vanusuri@mvista.com>
38---
39 tests/qemu-iotests/270 | 14 +++++++++++---
40 1 file changed, 11 insertions(+), 3 deletions(-)
41
42diff --git a/tests/qemu-iotests/270 b/tests/qemu-iotests/270
43index 74352342db..c37b674aa2 100755
44--- a/tests/qemu-iotests/270
45+++ b/tests/qemu-iotests/270
46@@ -60,8 +60,16 @@ _make_test_img -o cluster_size=2M,data_file="$TEST_IMG.orig" \
47 # "write" 2G of data without using any space.
48 # (qemu-img create does not like it, though, because null-co does not
49 # support image creation.)
50-$QEMU_IMG amend -o data_file="json:{'driver':'null-co',,'size':'4294967296'}" \
51- "$TEST_IMG"
52+test_img_with_null_data="json:{
53+ 'driver': '$IMGFMT',
54+ 'file': {
55+ 'filename': '$TEST_IMG'
56+ },
57+ 'data-file': {
58+ 'driver': 'null-co',
59+ 'size':'4294967296'
60+ }
61+}"
62
63 # This gives us a range of:
64 # 2^31 - 512 + 768 - 1 = 2^31 + 255 > 2^31
65@@ -74,7 +82,7 @@ $QEMU_IMG amend -o data_file="json:{'driver':'null-co',,'size':'4294967296'}" \
66 # on L2 boundaries, we need large L2 tables; hence the cluster size of
67 # 2 MB. (Anything from 256 kB should work, though, because then one L2
68 # table covers 8 GB.)
69-$QEMU_IO -c "write 768 $((2 ** 31 - 512))" "$TEST_IMG" | _filter_qemu_io
70+$QEMU_IO -c "write 768 $((2 ** 31 - 512))" "$test_img_with_null_data" | _filter_qemu_io
71
72 _check_test_img
73
74--
752.39.3
76
diff --git a/meta/recipes-devtools/qemu/qemu/CVE-2024-4467-0004.patch b/meta/recipes-devtools/qemu/qemu/CVE-2024-4467-0004.patch
new file mode 100644
index 0000000000..9fc653cbcb
--- /dev/null
+++ b/meta/recipes-devtools/qemu/qemu/CVE-2024-4467-0004.patch
@@ -0,0 +1,571 @@
1From 996680dd6d5afd51918e600126dbfed4dfe89e05 Mon Sep 17 00:00:00 2001
2From: Jon Maloy <jmaloy@redhat.com>
3Date: Sun, 9 Jun 2024 23:08:39 -0400
4Subject: [PATCH 4/5] block: introduce bdrv_open_file_child() helper
5
6RH-Author: Jon Maloy <jmaloy@redhat.com>
7RH-MergeRequest: 5: EMBARGOED CVE-2024-4467 for rhel-8.10.z (PRDSC)
8RH-Jira: RHEL-35616
9RH-CVE: CVE-2024-4467
10RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
11RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
12RH-Commit: [4/5] 9f582a9aff740eb9ec6f64bfec94854038d8545f
13
14Conflicts: - copy-before-write.c::cbw_copy() is an older version than
15 upstream, but introduction of the new function is
16 straight-forward.
17 - include/block/block-global-state.h doesn't exist in this
18 code version. Adding the prototype to
19 include/block/block.h instead.
20 - struct BlockDriver has no field 'filtered_child_is_backing'
21 We remove the corresponding assert() in the new function.
22
23commit 83930780325b144a5908c45b3957b9b6457b3831
24Author: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
25Date: Tue Jul 26 23:11:21 2022 +0300
26
27 block: introduce bdrv_open_file_child() helper
28
29 Almost all drivers call bdrv_open_child() similarly. Let's create a
30 helper for this.
31
32 The only not updated drivers that call bdrv_open_child() to set
33 bs->file are raw-format and snapshot-access:
34 raw-format sometimes want to have filtered child but
35 don't set drv->is_filter to true.
36 snapshot-access wants only DATA | PRIMARY
37
38 Possibly we should implement drv->is_filter_func() handler, to consider
39 raw-format as filter when it works as filter.. But it's another story.
40
41 Note also, that we decrease assignments to bs->file in code: it helps
42 us restrict modifying this field in further commit.
43
44 Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
45 Reviewed-by: Hanna Reitz <hreitz@redhat.com>
46 Message-Id: <20220726201134.924743-3-vsementsov@yandex-team.ru>
47 Reviewed-by: Kevin Wolf <kwolf@redhat.com>
48 Signed-off-by: Kevin Wolf <kwolf@redhat.com>
49
50Signed-off-by: Jon Maloy <jmaloy@redhat.com>
51
52Upstream-Status: Backport [import from rhel8 qemu-kvm-6.2.0-50.module+el8.10.0+22027+db0a70a4.src.rpm
53Upstream commit https://gitlab.com/qemu-project/qemu/-/commit/83930780325b144a5908c45b3957b9b6457b3831]
54CVE: CVE-2024-4467
55Signed-off-by: Vijay Anusuri <vanusuri@mvista.com>
56---
57 block.c | 18 ++++++++++++++++++
58 block/blkdebug.c | 9 +++------
59 block/blklogwrites.c | 7 ++-----
60 block/blkreplay.c | 7 ++-----
61 block/blkverify.c | 9 +++------
62 block/bochs.c | 7 +++----
63 block/cloop.c | 7 +++----
64 block/copy-before-write.c | 9 ++++-----
65 block/copy-on-read.c | 9 ++++-----
66 block/crypto.c | 11 ++++++-----
67 block/dmg.c | 7 +++----
68 block/filter-compress.c | 8 +++-----
69 block/parallels.c | 7 +++----
70 block/preallocate.c | 9 ++++-----
71 block/qcow.c | 6 ++----
72 block/qcow2.c | 8 ++++----
73 block/qed.c | 8 ++++----
74 block/replication.c | 8 +++-----
75 block/throttle.c | 8 +++-----
76 block/vdi.c | 7 +++----
77 block/vhdx.c | 7 +++----
78 block/vmdk.c | 7 +++----
79 block/vpc.c | 7 +++----
80 include/block/block.h | 3 +++
81 24 files changed, 92 insertions(+), 101 deletions(-)
82
83diff --git a/block.c b/block.c
84index 0ac5b163d2..889f878565 100644
85--- a/block.c
86+++ b/block.c
87@@ -3546,6 +3546,24 @@ BdrvChild *bdrv_open_child(const char *filename,
88 errp);
89 }
90
91+/*
92+ * Wrapper on bdrv_open_child() for most popular case: open primary child of bs.
93+ */
94+int bdrv_open_file_child(const char *filename,
95+ QDict *options, const char *bdref_key,
96+ BlockDriverState *parent, Error **errp)
97+{
98+ BdrvChildRole role;
99+
100+ role = parent->drv->is_filter ?
101+ (BDRV_CHILD_FILTERED | BDRV_CHILD_PRIMARY) : BDRV_CHILD_IMAGE;
102+
103+ parent->file = bdrv_open_child(filename, options, bdref_key, parent,
104+ &child_of_bds, role, false, errp);
105+
106+ return parent->file ? 0 : -EINVAL;
107+}
108+
109 /*
110 * TODO Future callers may need to specify parent/child_class in order for
111 * option inheritance to work. Existing callers use it for the root node.
112diff --git a/block/blkdebug.c b/block/blkdebug.c
113index bbf2948703..5fcfc8ac6f 100644
114--- a/block/blkdebug.c
115+++ b/block/blkdebug.c
116@@ -503,12 +503,9 @@ static int blkdebug_open(BlockDriverState *bs, QDict *options, int flags,
117 }
118
119 /* Open the image file */
120- bs->file = bdrv_open_child(qemu_opt_get(opts, "x-image"), options, "image",
121- bs, &child_of_bds,
122- BDRV_CHILD_FILTERED | BDRV_CHILD_PRIMARY,
123- false, errp);
124- if (!bs->file) {
125- ret = -EINVAL;
126+ ret = bdrv_open_file_child(qemu_opt_get(opts, "x-image"), options, "image",
127+ bs, errp);
128+ if (ret < 0) {
129 goto out;
130 }
131
132diff --git a/block/blklogwrites.c b/block/blklogwrites.c
133index f7a251e91f..f66a617eb3 100644
134--- a/block/blklogwrites.c
135+++ b/block/blklogwrites.c
136@@ -155,11 +155,8 @@ static int blk_log_writes_open(BlockDriverState *bs, QDict *options, int flags,
137 }
138
139 /* Open the file */
140- bs->file = bdrv_open_child(NULL, options, "file", bs, &child_of_bds,
141- BDRV_CHILD_FILTERED | BDRV_CHILD_PRIMARY, false,
142- errp);
143- if (!bs->file) {
144- ret = -EINVAL;
145+ ret = bdrv_open_file_child(NULL, options, "file", bs, errp);
146+ if (ret < 0) {
147 goto fail;
148 }
149
150diff --git a/block/blkreplay.c b/block/blkreplay.c
151index dcbe780ddb..76a0b8d12a 100644
152--- a/block/blkreplay.c
153+++ b/block/blkreplay.c
154@@ -26,11 +26,8 @@ static int blkreplay_open(BlockDriverState *bs, QDict *options, int flags,
155 int ret;
156
157 /* Open the image file */
158- bs->file = bdrv_open_child(NULL, options, "image", bs, &child_of_bds,
159- BDRV_CHILD_FILTERED | BDRV_CHILD_PRIMARY,
160- false, errp);
161- if (!bs->file) {
162- ret = -EINVAL;
163+ ret = bdrv_open_file_child(NULL, options, "image", bs, errp);
164+ if (ret < 0) {
165 goto fail;
166 }
167
168diff --git a/block/blkverify.c b/block/blkverify.c
169index d1facf5ba9..920e891684 100644
170--- a/block/blkverify.c
171+++ b/block/blkverify.c
172@@ -121,12 +121,9 @@ static int blkverify_open(BlockDriverState *bs, QDict *options, int flags,
173 }
174
175 /* Open the raw file */
176- bs->file = bdrv_open_child(qemu_opt_get(opts, "x-raw"), options, "raw",
177- bs, &child_of_bds,
178- BDRV_CHILD_FILTERED | BDRV_CHILD_PRIMARY,
179- false, errp);
180- if (!bs->file) {
181- ret = -EINVAL;
182+ ret = bdrv_open_file_child(qemu_opt_get(opts, "x-raw"), options, "raw",
183+ bs, errp);
184+ if (ret < 0) {
185 goto fail;
186 }
187
188diff --git a/block/bochs.c b/block/bochs.c
189index 4d68658087..b2dc06bbfd 100644
190--- a/block/bochs.c
191+++ b/block/bochs.c
192@@ -110,10 +110,9 @@ static int bochs_open(BlockDriverState *bs, QDict *options, int flags,
193 return ret;
194 }
195
196- bs->file = bdrv_open_child(NULL, options, "file", bs, &child_of_bds,
197- BDRV_CHILD_IMAGE, false, errp);
198- if (!bs->file) {
199- return -EINVAL;
200+ ret = bdrv_open_file_child(NULL, options, "file", bs, errp);
201+ if (ret < 0) {
202+ return ret;
203 }
204
205 ret = bdrv_pread(bs->file, 0, &bochs, sizeof(bochs));
206diff --git a/block/cloop.c b/block/cloop.c
207index b8c6d0eccd..bee87da173 100644
208--- a/block/cloop.c
209+++ b/block/cloop.c
210@@ -71,10 +71,9 @@ static int cloop_open(BlockDriverState *bs, QDict *options, int flags,
211 return ret;
212 }
213
214- bs->file = bdrv_open_child(NULL, options, "file", bs, &child_of_bds,
215- BDRV_CHILD_IMAGE, false, errp);
216- if (!bs->file) {
217- return -EINVAL;
218+ ret = bdrv_open_file_child(NULL, options, "file", bs, errp);
219+ if (ret < 0) {
220+ return ret;
221 }
222
223 /* read header */
224diff --git a/block/copy-before-write.c b/block/copy-before-write.c
225index c30a5ff8de..8aa2cb6a85 100644
226--- a/block/copy-before-write.c
227+++ b/block/copy-before-write.c
228@@ -150,12 +150,11 @@ static int cbw_open(BlockDriverState *bs, QDict *options, int flags,
229 {
230 BDRVCopyBeforeWriteState *s = bs->opaque;
231 BdrvDirtyBitmap *copy_bitmap;
232+ int ret;
233
234- bs->file = bdrv_open_child(NULL, options, "file", bs, &child_of_bds,
235- BDRV_CHILD_FILTERED | BDRV_CHILD_PRIMARY,
236- false, errp);
237- if (!bs->file) {
238- return -EINVAL;
239+ ret = bdrv_open_file_child(NULL, options, "file", bs, errp);
240+ if (ret < 0) {
241+ return ret;
242 }
243
244 s->target = bdrv_open_child(NULL, options, "target", bs, &child_of_bds,
245diff --git a/block/copy-on-read.c b/block/copy-on-read.c
246index 1fc7fb3333..815ac1d835 100644
247--- a/block/copy-on-read.c
248+++ b/block/copy-on-read.c
249@@ -41,12 +41,11 @@ static int cor_open(BlockDriverState *bs, QDict *options, int flags,
250 BDRVStateCOR *state = bs->opaque;
251 /* Find a bottom node name, if any */
252 const char *bottom_node = qdict_get_try_str(options, "bottom");
253+ int ret;
254
255- bs->file = bdrv_open_child(NULL, options, "file", bs, &child_of_bds,
256- BDRV_CHILD_FILTERED | BDRV_CHILD_PRIMARY,
257- false, errp);
258- if (!bs->file) {
259- return -EINVAL;
260+ ret = bdrv_open_file_child(NULL, options, "file", bs, errp);
261+ if (ret < 0) {
262+ return ret;
263 }
264
265 bs->supported_read_flags = BDRV_REQ_PREFETCH;
266diff --git a/block/crypto.c b/block/crypto.c
267index c8ba4681e2..abfce39230 100644
268--- a/block/crypto.c
269+++ b/block/crypto.c
270@@ -260,15 +260,14 @@ static int block_crypto_open_generic(QCryptoBlockFormat format,
271 {
272 BlockCrypto *crypto = bs->opaque;
273 QemuOpts *opts = NULL;
274- int ret = -EINVAL;
275+ int ret;
276 QCryptoBlockOpenOptions *open_opts = NULL;
277 unsigned int cflags = 0;
278 QDict *cryptoopts = NULL;
279
280- bs->file = bdrv_open_child(NULL, options, "file", bs, &child_of_bds,
281- BDRV_CHILD_IMAGE, false, errp);
282- if (!bs->file) {
283- return -EINVAL;
284+ ret = bdrv_open_file_child(NULL, options, "file", bs, errp);
285+ if (ret < 0) {
286+ return ret;
287 }
288
289 bs->supported_write_flags = BDRV_REQ_FUA &
290@@ -276,6 +275,7 @@ static int block_crypto_open_generic(QCryptoBlockFormat format,
291
292 opts = qemu_opts_create(opts_spec, NULL, 0, &error_abort);
293 if (!qemu_opts_absorb_qdict(opts, options, errp)) {
294+ ret = -EINVAL;
295 goto cleanup;
296 }
297
298@@ -284,6 +284,7 @@ static int block_crypto_open_generic(QCryptoBlockFormat format,
299
300 open_opts = block_crypto_open_opts_init(cryptoopts, errp);
301 if (!open_opts) {
302+ ret = -EINVAL;
303 goto cleanup;
304 }
305
306diff --git a/block/dmg.c b/block/dmg.c
307index 447901fbb8..38c363dd39 100644
308--- a/block/dmg.c
309+++ b/block/dmg.c
310@@ -439,10 +439,9 @@ static int dmg_open(BlockDriverState *bs, QDict *options, int flags,
311 return ret;
312 }
313
314- bs->file = bdrv_open_child(NULL, options, "file", bs, &child_of_bds,
315- BDRV_CHILD_IMAGE, false, errp);
316- if (!bs->file) {
317- return -EINVAL;
318+ ret = bdrv_open_file_child(NULL, options, "file", bs, errp);
319+ if (ret < 0) {
320+ return ret;
321 }
322
323 block_module_load_one("dmg-bz2");
324diff --git a/block/filter-compress.c b/block/filter-compress.c
325index d5be538619..305716c86c 100644
326--- a/block/filter-compress.c
327+++ b/block/filter-compress.c
328@@ -30,11 +30,9 @@
329 static int compress_open(BlockDriverState *bs, QDict *options, int flags,
330 Error **errp)
331 {
332- bs->file = bdrv_open_child(NULL, options, "file", bs, &child_of_bds,
333- BDRV_CHILD_FILTERED | BDRV_CHILD_PRIMARY,
334- false, errp);
335- if (!bs->file) {
336- return -EINVAL;
337+ int ret = bdrv_open_file_child(NULL, options, "file", bs, errp);
338+ if (ret < 0) {
339+ return ret;
340 }
341
342 if (!bs->file->bs->drv || !block_driver_can_compress(bs->file->bs->drv)) {
343diff --git a/block/parallels.c b/block/parallels.c
344index 6ebad2a2bb..ed4debd899 100644
345--- a/block/parallels.c
346+++ b/block/parallels.c
347@@ -735,10 +735,9 @@ static int parallels_open(BlockDriverState *bs, QDict *options, int flags,
348 Error *local_err = NULL;
349 char *buf;
350
351- bs->file = bdrv_open_child(NULL, options, "file", bs, &child_of_bds,
352- BDRV_CHILD_IMAGE, false, errp);
353- if (!bs->file) {
354- return -EINVAL;
355+ ret = bdrv_open_file_child(NULL, options, "file", bs, errp);
356+ if (ret < 0) {
357+ return ret;
358 }
359
360 ret = bdrv_pread(bs->file, 0, &ph, sizeof(ph));
361diff --git a/block/preallocate.c b/block/preallocate.c
362index 1d4233f730..332408bdc9 100644
363--- a/block/preallocate.c
364+++ b/block/preallocate.c
365@@ -134,6 +134,7 @@ static int preallocate_open(BlockDriverState *bs, QDict *options, int flags,
366 Error **errp)
367 {
368 BDRVPreallocateState *s = bs->opaque;
369+ int ret;
370
371 /*
372 * s->data_end and friends should be initialized on permission update.
373@@ -141,11 +142,9 @@ static int preallocate_open(BlockDriverState *bs, QDict *options, int flags,
374 */
375 s->file_end = s->zero_start = s->data_end = -EINVAL;
376
377- bs->file = bdrv_open_child(NULL, options, "file", bs, &child_of_bds,
378- BDRV_CHILD_FILTERED | BDRV_CHILD_PRIMARY,
379- false, errp);
380- if (!bs->file) {
381- return -EINVAL;
382+ ret = bdrv_open_file_child(NULL, options, "file", bs, errp);
383+ if (ret < 0) {
384+ return ret;
385 }
386
387 if (!preallocate_absorb_opts(&s->opts, options, bs->file->bs, errp)) {
388diff --git a/block/qcow.c b/block/qcow.c
389index c39940f33e..544a17261f 100644
390--- a/block/qcow.c
391+++ b/block/qcow.c
392@@ -120,10 +120,8 @@ static int qcow_open(BlockDriverState *bs, QDict *options, int flags,
393 qdict_extract_subqdict(options, &encryptopts, "encrypt.");
394 encryptfmt = qdict_get_try_str(encryptopts, "format");
395
396- bs->file = bdrv_open_child(NULL, options, "file", bs, &child_of_bds,
397- BDRV_CHILD_IMAGE, false, errp);
398- if (!bs->file) {
399- ret = -EINVAL;
400+ ret = bdrv_open_file_child(NULL, options, "file", bs, errp);
401+ if (ret < 0) {
402 goto fail;
403 }
404
405diff --git a/block/qcow2.c b/block/qcow2.c
406index 6ee1919612..29ea157e6b 100644
407--- a/block/qcow2.c
408+++ b/block/qcow2.c
409@@ -1907,11 +1907,11 @@ static int qcow2_open(BlockDriverState *bs, QDict *options, int flags,
410 .errp = errp,
411 .ret = -EINPROGRESS
412 };
413+ int ret;
414
415- bs->file = bdrv_open_child(NULL, options, "file", bs, &child_of_bds,
416- BDRV_CHILD_IMAGE, false, errp);
417- if (!bs->file) {
418- return -EINVAL;
419+ ret = bdrv_open_file_child(NULL, options, "file", bs, errp);
420+ if (ret < 0) {
421+ return ret;
422 }
423
424 /* Initialise locks */
425diff --git a/block/qed.c b/block/qed.c
426index 558d3646c4..e3b06a3d00 100644
427--- a/block/qed.c
428+++ b/block/qed.c
429@@ -558,11 +558,11 @@ static int bdrv_qed_open(BlockDriverState *bs, QDict *options, int flags,
430 .errp = errp,
431 .ret = -EINPROGRESS
432 };
433+ int ret;
434
435- bs->file = bdrv_open_child(NULL, options, "file", bs, &child_of_bds,
436- BDRV_CHILD_IMAGE, false, errp);
437- if (!bs->file) {
438- return -EINVAL;
439+ ret = bdrv_open_file_child(NULL, options, "file", bs, errp);
440+ if (ret < 0) {
441+ return ret;
442 }
443
444 bdrv_qed_init_state(bs);
445diff --git a/block/replication.c b/block/replication.c
446index 55c8f894aa..2f17397764 100644
447--- a/block/replication.c
448+++ b/block/replication.c
449@@ -88,11 +88,9 @@ static int replication_open(BlockDriverState *bs, QDict *options,
450 const char *mode;
451 const char *top_id;
452
453- bs->file = bdrv_open_child(NULL, options, "file", bs, &child_of_bds,
454- BDRV_CHILD_FILTERED | BDRV_CHILD_PRIMARY,
455- false, errp);
456- if (!bs->file) {
457- return -EINVAL;
458+ ret = bdrv_open_file_child(NULL, options, "file", bs, errp);
459+ if (ret < 0) {
460+ return ret;
461 }
462
463 ret = -EINVAL;
464diff --git a/block/throttle.c b/block/throttle.c
465index 6e8d52fa24..4fb5798c27 100644
466--- a/block/throttle.c
467+++ b/block/throttle.c
468@@ -78,11 +78,9 @@ static int throttle_open(BlockDriverState *bs, QDict *options,
469 char *group;
470 int ret;
471
472- bs->file = bdrv_open_child(NULL, options, "file", bs, &child_of_bds,
473- BDRV_CHILD_FILTERED | BDRV_CHILD_PRIMARY,
474- false, errp);
475- if (!bs->file) {
476- return -EINVAL;
477+ ret = bdrv_open_file_child(NULL, options, "file", bs, errp);
478+ if (ret < 0) {
479+ return ret;
480 }
481 bs->supported_write_flags = bs->file->bs->supported_write_flags |
482 BDRV_REQ_WRITE_UNCHANGED;
483diff --git a/block/vdi.c b/block/vdi.c
484index bdc58d726e..c50c0ed61f 100644
485--- a/block/vdi.c
486+++ b/block/vdi.c
487@@ -376,10 +376,9 @@ static int vdi_open(BlockDriverState *bs, QDict *options, int flags,
488 int ret;
489 QemuUUID uuid_link, uuid_parent;
490
491- bs->file = bdrv_open_child(NULL, options, "file", bs, &child_of_bds,
492- BDRV_CHILD_IMAGE, false, errp);
493- if (!bs->file) {
494- return -EINVAL;
495+ ret = bdrv_open_file_child(NULL, options, "file", bs, errp);
496+ if (ret < 0) {
497+ return ret;
498 }
499
500 logout("\n");
501diff --git a/block/vhdx.c b/block/vhdx.c
502index 356ec4c455..e7d6d7509a 100644
503--- a/block/vhdx.c
504+++ b/block/vhdx.c
505@@ -996,10 +996,9 @@ static int vhdx_open(BlockDriverState *bs, QDict *options, int flags,
506 uint64_t signature;
507 Error *local_err = NULL;
508
509- bs->file = bdrv_open_child(NULL, options, "file", bs, &child_of_bds,
510- BDRV_CHILD_IMAGE, false, errp);
511- if (!bs->file) {
512- return -EINVAL;
513+ ret = bdrv_open_file_child(NULL, options, "file", bs, errp);
514+ if (ret < 0) {
515+ return ret;
516 }
517
518 s->bat = NULL;
519diff --git a/block/vmdk.c b/block/vmdk.c
520index 0dfab6e941..7d7e56b36c 100644
521--- a/block/vmdk.c
522+++ b/block/vmdk.c
523@@ -1262,10 +1262,9 @@ static int vmdk_open(BlockDriverState *bs, QDict *options, int flags,
524 BDRVVmdkState *s = bs->opaque;
525 uint32_t magic;
526
527- bs->file = bdrv_open_child(NULL, options, "file", bs, &child_of_bds,
528- BDRV_CHILD_IMAGE, false, errp);
529- if (!bs->file) {
530- return -EINVAL;
531+ ret = bdrv_open_file_child(NULL, options, "file", bs, errp);
532+ if (ret < 0) {
533+ return ret;
534 }
535
536 buf = vmdk_read_desc(bs->file, 0, errp);
537diff --git a/block/vpc.c b/block/vpc.c
538index 297a26262a..430cab1cbb 100644
539--- a/block/vpc.c
540+++ b/block/vpc.c
541@@ -232,10 +232,9 @@ static int vpc_open(BlockDriverState *bs, QDict *options, int flags,
542 int ret;
543 int64_t bs_size;
544
545- bs->file = bdrv_open_child(NULL, options, "file", bs, &child_of_bds,
546- BDRV_CHILD_IMAGE, false, errp);
547- if (!bs->file) {
548- return -EINVAL;
549+ ret = bdrv_open_file_child(NULL, options, "file", bs, errp);
550+ if (ret < 0) {
551+ return ret;
552 }
553
554 opts = qemu_opts_create(&vpc_runtime_opts, NULL, 0, &error_abort);
555diff --git a/include/block/block.h b/include/block/block.h
556index e5dd22b034..f885f113ef 100644
557--- a/include/block/block.h
558+++ b/include/block/block.h
559@@ -376,6 +376,9 @@ BdrvChild *bdrv_open_child(const char *filename,
560 const BdrvChildClass *child_class,
561 BdrvChildRole child_role,
562 bool allow_none, Error **errp);
563+int bdrv_open_file_child(const char *filename,
564+ QDict *options, const char *bdref_key,
565+ BlockDriverState *parent, Error **errp);
566 BlockDriverState *bdrv_open_blockdev_ref(BlockdevRef *ref, Error **errp);
567 int bdrv_set_backing_hd(BlockDriverState *bs, BlockDriverState *backing_hd,
568 Error **errp);
569--
5702.39.3
571
diff --git a/meta/recipes-devtools/qemu/qemu/CVE-2024-4467-0005.patch b/meta/recipes-devtools/qemu/qemu/CVE-2024-4467-0005.patch
new file mode 100644
index 0000000000..94e03d8646
--- /dev/null
+++ b/meta/recipes-devtools/qemu/qemu/CVE-2024-4467-0005.patch
@@ -0,0 +1,265 @@
1From c4ba1f1755031a0ac2f600ed8c17e7dcb6b2b857 Mon Sep 17 00:00:00 2001
2From: Jon Maloy <jmaloy@redhat.com>
3Date: Wed, 5 Jun 2024 19:56:51 -0400
4Subject: [PATCH 5/5] block: Parse filenames only when explicitly requested
5
6RH-Author: Jon Maloy <jmaloy@redhat.com>
7RH-MergeRequest: 5: EMBARGOED CVE-2024-4467 for rhel-8.10.z (PRDSC)
8RH-Jira: RHEL-35616
9RH-CVE: CVE-2024-4467
10RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
11RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
12RH-Commit: [5/5] a3e197add64fc6950c4ac576e34d833dfae7ee34
13
14Conflicts: - brdv_open_child_common(): bdrv_graph_wrlock/unlock()
15 don't exist in this code version. We ignore them.
16 bdrv_open_inherit(): no_coroutine_fn/GRAPH_UNLOCKED
17 doesn't exist. We ignore it.
18 - Changes to bdrv_open_file_child() didn't apply cleanly,
19 but fixing it is straight-forward.
20 - GLOBAL_STATE_CODE() not present in this code. Ignoring it.
21 - bdrv_open_file_child(): Need to continue setting of
22 parent->file.
23
24commit f44c2941d4419e60f16dea3e9adca164e75aa78d
25Author: Kevin Wolf <kwolf@redhat.com>
26Date: Thu Apr 25 14:56:02 2024 +0200
27
28 block: Parse filenames only when explicitly requested
29
30 When handling image filenames from legacy options such as -drive or from
31 tools, these filenames are parsed for protocol prefixes, including for
32 the json:{} pseudo-protocol.
33
34 This behaviour is intended for filenames that come directly from the
35 command line and for backing files, which may come from the image file
36 itself. Higher level management tools generally take care to verify that
37 untrusted images don't contain a bad (or any) backing file reference;
38 'qemu-img info' is a suitable tool for this.
39
40 However, for other files that can be referenced in images, such as
41 qcow2 data files or VMDK extents, the string from the image file is
42 usually not verified by management tools - and 'qemu-img info' wouldn't
43 be suitable because in contrast to backing files, it already opens these
44 other referenced files. So here the string should be interpreted as a
45 literal local filename. More complex configurations need to be specified
46 explicitly on the command line or in QMP.
47
48 This patch changes bdrv_open_inherit() so that it only parses filenames
49 if a new parameter parse_filename is true. It is set for the top level
50 in bdrv_open(), for the file child and for the backing file child. All
51 other callers pass false and disable filename parsing this way.
52
53 Signed-off-by: Kevin Wolf <kwolf@redhat.com>
54 Reviewed-by: Eric Blake <eblake@redhat.com>
55 Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
56 Reviewed-by: Hanna Czenczek <hreitz@redhat.com>
57 Upstream: N/A, embargoed
58 Signed-off-by: Hanna Czenczek <hreitz@redhat.com>
59
60Signed-off-by: Jon Maloy <jmaloy@redhat.com>
61
62Upstream-Status: Backport [import from rhel8 qemu-kvm-6.2.0-50.module+el8.10.0+22027+db0a70a4.src.rpm
63Upstream commit https://gitlab.com/qemu-project/qemu/-/commit/7ead946998610657d38d1a505d5f25300d4ca613]
64CVE: CVE-2024-4467
65Signed-off-by: Vijay Anusuri <vanusuri@mvista.com>
66---
67 block.c | 81 +++++++++++++++++++++++++++++++++++++++------------------
68 1 file changed, 56 insertions(+), 25 deletions(-)
69
70diff --git a/block.c b/block.c
71index 889f878565..ddebf50efa 100644
72--- a/block.c
73+++ b/block.c
74@@ -82,6 +82,7 @@ static BlockDriverState *bdrv_open_inherit(const char *filename,
75 BlockDriverState *parent,
76 const BdrvChildClass *child_class,
77 BdrvChildRole child_role,
78+ bool parse_filename,
79 Error **errp);
80
81 static bool bdrv_recurse_has_child(BlockDriverState *bs,
82@@ -1926,7 +1927,8 @@ static void parse_json_protocol(QDict *options, const char **pfilename,
83 * block driver has been specified explicitly.
84 */
85 static int bdrv_fill_options(QDict **options, const char *filename,
86- int *flags, Error **errp)
87+ int *flags, bool allow_parse_filename,
88+ Error **errp)
89 {
90 const char *drvname;
91 bool protocol = *flags & BDRV_O_PROTOCOL;
92@@ -1966,7 +1968,7 @@ static int bdrv_fill_options(QDict **options, const char *filename,
93 if (protocol && filename) {
94 if (!qdict_haskey(*options, "filename")) {
95 qdict_put_str(*options, "filename", filename);
96- parse_filename = true;
97+ parse_filename = allow_parse_filename;
98 } else {
99 error_setg(errp, "Can't specify 'file' and 'filename' options at "
100 "the same time");
101@@ -3439,7 +3441,8 @@ int bdrv_open_backing_file(BlockDriverState *bs, QDict *parent_options,
102 }
103
104 backing_hd = bdrv_open_inherit(backing_filename, reference, options, 0, bs,
105- &child_of_bds, bdrv_backing_role(bs), errp);
106+ &child_of_bds, bdrv_backing_role(bs), true,
107+ errp);
108 if (!backing_hd) {
109 bs->open_flags |= BDRV_O_NO_BACKING;
110 error_prepend(errp, "Could not open backing file: ");
111@@ -3472,7 +3475,8 @@ free_exit:
112 static BlockDriverState *
113 bdrv_open_child_bs(const char *filename, QDict *options, const char *bdref_key,
114 BlockDriverState *parent, const BdrvChildClass *child_class,
115- BdrvChildRole child_role, bool allow_none, Error **errp)
116+ BdrvChildRole child_role, bool allow_none,
117+ bool parse_filename, Error **errp)
118 {
119 BlockDriverState *bs = NULL;
120 QDict *image_options;
121@@ -3503,7 +3507,8 @@ bdrv_open_child_bs(const char *filename, QDict *options, const char *bdref_key,
122 }
123
124 bs = bdrv_open_inherit(filename, reference, image_options, 0,
125- parent, child_class, child_role, errp);
126+ parent, child_class, child_role, parse_filename,
127+ errp);
128 if (!bs) {
129 goto done;
130 }
131@@ -3513,6 +3518,29 @@ done:
132 return bs;
133 }
134
135+static BdrvChild *bdrv_open_child_common(const char *filename,
136+ QDict *options, const char *bdref_key,
137+ BlockDriverState *parent,
138+ const BdrvChildClass *child_class,
139+ BdrvChildRole child_role,
140+ bool allow_none, bool parse_filename,
141+ Error **errp)
142+{
143+ BlockDriverState *bs;
144+ BdrvChild *child;
145+
146+ bs = bdrv_open_child_bs(filename, options, bdref_key, parent, child_class,
147+ child_role, allow_none, parse_filename, errp);
148+ if (bs == NULL) {
149+ return NULL;
150+ }
151+
152+ child = bdrv_attach_child(parent, bs, bdref_key, child_class, child_role,
153+ errp);
154+
155+ return child;
156+}
157+
158 /*
159 * Opens a disk image whose options are given as BlockdevRef in another block
160 * device's options.
161@@ -3534,20 +3562,17 @@ BdrvChild *bdrv_open_child(const char *filename,
162 BdrvChildRole child_role,
163 bool allow_none, Error **errp)
164 {
165- BlockDriverState *bs;
166-
167- bs = bdrv_open_child_bs(filename, options, bdref_key, parent, child_class,
168- child_role, allow_none, errp);
169- if (bs == NULL) {
170- return NULL;
171- }
172-
173- return bdrv_attach_child(parent, bs, bdref_key, child_class, child_role,
174- errp);
175+ return bdrv_open_child_common(filename, options, bdref_key, parent,
176+ child_class, child_role, allow_none, false,
177+ errp);
178 }
179
180 /*
181- * Wrapper on bdrv_open_child() for most popular case: open primary child of bs.
182+ * This does mostly the same as bdrv_open_child(), but for opening the primary
183+ * child of a node. A notable difference from bdrv_open_child() is that it
184+ * enables filename parsing for protocol names (including json:).
185+ *
186+ * @parent can move to a different AioContext in this function.
187 */
188 int bdrv_open_file_child(const char *filename,
189 QDict *options, const char *bdref_key,
190@@ -3558,8 +3583,9 @@ int bdrv_open_file_child(const char *filename,
191 role = parent->drv->is_filter ?
192 (BDRV_CHILD_FILTERED | BDRV_CHILD_PRIMARY) : BDRV_CHILD_IMAGE;
193
194- parent->file = bdrv_open_child(filename, options, bdref_key, parent,
195- &child_of_bds, role, false, errp);
196+ parent->file = bdrv_open_child_common(filename, options, bdref_key, parent,
197+ &child_of_bds, role, false, true,
198+ errp);
199
200 return parent->file ? 0 : -EINVAL;
201 }
202@@ -3599,7 +3625,8 @@ BlockDriverState *bdrv_open_blockdev_ref(BlockdevRef *ref, Error **errp)
203
204 }
205
206- bs = bdrv_open_inherit(NULL, reference, qdict, 0, NULL, NULL, 0, errp);
207+ bs = bdrv_open_inherit(NULL, reference, qdict, 0, NULL, NULL, 0, false,
208+ errp);
209 obj = NULL;
210 qobject_unref(obj);
211 visit_free(v);
212@@ -3690,6 +3717,7 @@ static BlockDriverState *bdrv_open_inherit(const char *filename,
213 BlockDriverState *parent,
214 const BdrvChildClass *child_class,
215 BdrvChildRole child_role,
216+ bool parse_filename,
217 Error **errp)
218 {
219 int ret;
220@@ -3733,9 +3761,11 @@ static BlockDriverState *bdrv_open_inherit(const char *filename,
221 }
222
223 /* json: syntax counts as explicit options, as if in the QDict */
224- parse_json_protocol(options, &filename, &local_err);
225- if (local_err) {
226- goto fail;
227+ if (parse_filename) {
228+ parse_json_protocol(options, &filename, &local_err);
229+ if (local_err) {
230+ goto fail;
231+ }
232 }
233
234 bs->explicit_options = qdict_clone_shallow(options);
235@@ -3760,7 +3790,8 @@ static BlockDriverState *bdrv_open_inherit(const char *filename,
236 parent->open_flags, parent->options);
237 }
238
239- ret = bdrv_fill_options(&options, filename, &flags, &local_err);
240+ ret = bdrv_fill_options(&options, filename, &flags, parse_filename,
241+ &local_err);
242 if (ret < 0) {
243 goto fail;
244 }
245@@ -3829,7 +3860,7 @@ static BlockDriverState *bdrv_open_inherit(const char *filename,
246
247 file_bs = bdrv_open_child_bs(filename, options, "file", bs,
248 &child_of_bds, BDRV_CHILD_IMAGE,
249- true, &local_err);
250+ true, true, &local_err);
251 if (local_err) {
252 goto fail;
253 }
254@@ -3974,7 +4005,7 @@ BlockDriverState *bdrv_open(const char *filename, const char *reference,
255 QDict *options, int flags, Error **errp)
256 {
257 return bdrv_open_inherit(filename, reference, options, flags, NULL,
258- NULL, 0, errp);
259+ NULL, 0, true, errp);
260 }
261
262 /* Return true if the NULL-terminated @list contains @str */
263--
2642.39.3
265