summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHitendra Prajapati <hprajapati@mvista.com>2024-06-26 11:53:58 +0530
committerBruce Ashfield <bruce.ashfield@gmail.com>2024-07-10 03:54:05 +0000
commite892261291b22c7971e6f2ed31b1019ddb56517e (patch)
treeabb679fb9c3af5f898ffbac383b493a5f9bb8d24
parent37c06acf58f9020bccfc61954eeefe160642d5f3 (diff)
downloadmeta-virtualization-e892261291b22c7971e6f2ed31b1019ddb56517e.tar.gz
libvirt: fix multiple CVEs
Backport fixes for: * CVE-2024-1441 - Upstream-Status: Backport from https://gitlab.com/libvirt/libvirt/-/commit/c664015fe3a7bf59db26686e9ed69af011c6ebb8 * CVE-2024-2494 - Upstream-Status: Backport from https://gitlab.com/libvirt/libvirt/-/commit/8a3f8d957507c1f8223fdcf25a3ff885b15557f2 * CVE-2024-4418 - Upstream-Status: Backport from https://gitlab.com/libvirt/libvirt/-/commit/8074d64dc2eca846d6a61efe1a9b7428a0ce1dd1 Signed-off-by: Hitendra Prajapati <hprajapati@mvista.com> Signed-off-by: Bruce Ashfield <bruce.ashfield@gmail.com>
-rw-r--r--recipes-extended/libvirt/libvirt/CVE-2024-1441.patch70
-rw-r--r--recipes-extended/libvirt/libvirt/CVE-2024-2494.patch220
-rw-r--r--recipes-extended/libvirt/libvirt/CVE-2024-4418.patch86
-rw-r--r--recipes-extended/libvirt/libvirt_10.0.0.bb3
4 files changed, 379 insertions, 0 deletions
diff --git a/recipes-extended/libvirt/libvirt/CVE-2024-1441.patch b/recipes-extended/libvirt/libvirt/CVE-2024-1441.patch
new file mode 100644
index 00000000..3fbf1d52
--- /dev/null
+++ b/recipes-extended/libvirt/libvirt/CVE-2024-1441.patch
@@ -0,0 +1,70 @@
1From c664015fe3a7bf59db26686e9ed69af011c6ebb8 Mon Sep 17 00:00:00 2001
2From: Martin Kletzander <mkletzan@redhat.com>
3Date: Tue, 27 Feb 2024 16:20:12 +0100
4Subject: [PATCH] Fix off-by-one error in udevListInterfacesByStatus
5MIME-Version: 1.0
6Content-Type: text/plain; charset=UTF-8
7Content-Transfer-Encoding: 8bit
8
9Ever since this function was introduced in 2012 it could've tried
10filling in an extra interface name. That was made worse in 2019 when
11the caller functions started accepting NULL arrays of size 0.
12
13This is assigned CVE-2024-1441.
14
15Signed-off-by: Martin Kletzander <mkletzan@redhat.com>
16Reported-by: Alexander Kuznetsov <kuznetsovam@altlinux.org>
17Fixes: 5a33366f5c0b18c93d161bd144f9f079de4ac8ca
18Fixes: d6064e2759a24e0802f363e3a810dc5a7d7ebb15
19Reviewed-by: Ján Tomko <jtomko@redhat.com>
20
21Upstream-Status: Backport [https://gitlab.com/libvirt/libvirt/-/commit/c664015fe3a7bf59db26686e9ed69af011c6ebb8]
22CVE: CVE-2024-1441
23Signed-off-by: Hitendra Prajapati <hprajapati@mvista.com>
24---
25 NEWS.rst | 15 +++++++++++++++
26 src/interface/interface_backend_udev.c | 2 +-
27 2 files changed, 16 insertions(+), 1 deletion(-)
28
29diff --git a/NEWS.rst b/NEWS.rst
30index d013fc7..25f2038 100644
31--- a/NEWS.rst
32+++ b/NEWS.rst
33@@ -557,6 +557,21 @@ v9.2.0 (2023-04-01)
34 v9.1.0 (2023-03-01)
35 ===================
36
37+ * ``CVE-2024-1441``: Fix off-by-one error leading to a crash
38+
39+ In **libvirt-1.0.0** there were couple of interface listing APIs
40+ introduced which had an off-by-one error. That error could lead to a
41+ very rare crash if an array was passed to those functions which did
42+ not fit all the interfaces.
43+
44+ In **libvirt-5.10** a check for non-NULL arrays has been adjusted to
45+ allow for NULL arrays with size 0 instead of rejecting all NULL
46+ arrays. However that made the above issue significantly worse since
47+ that off-by-one error now did not write beyond an array, but
48+ dereferenced said NULL pointer making the crash certain in a
49+ specific scenario in which a NULL array of size 0 was passed to the
50+ aforementioned functions.
51+
52 * **Removed features**
53
54 * vbox: removed support for version 5.2 and 6.0 APIs
55diff --git a/src/interface/interface_backend_udev.c b/src/interface/interface_backend_udev.c
56index fb6799e..4091483 100644
57--- a/src/interface/interface_backend_udev.c
58+++ b/src/interface/interface_backend_udev.c
59@@ -222,7 +222,7 @@ udevListInterfacesByStatus(virConnectPtr conn,
60 g_autoptr(virInterfaceDef) def = NULL;
61
62 /* Ensure we won't exceed the size of our array */
63- if (count > names_len)
64+ if (count >= names_len)
65 break;
66
67 path = udev_list_entry_get_name(dev_entry);
68--
692.25.1
70
diff --git a/recipes-extended/libvirt/libvirt/CVE-2024-2494.patch b/recipes-extended/libvirt/libvirt/CVE-2024-2494.patch
new file mode 100644
index 00000000..6b38f13a
--- /dev/null
+++ b/recipes-extended/libvirt/libvirt/CVE-2024-2494.patch
@@ -0,0 +1,220 @@
1From 8a3f8d957507c1f8223fdcf25a3ff885b15557f2 Mon Sep 17 00:00:00 2001
2From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= <berrange@redhat.com>
3Date: Fri, 15 Mar 2024 10:47:50 +0000
4Subject: [PATCH] remote: check for negative array lengths before allocation
5MIME-Version: 1.0
6Content-Type: text/plain; charset=UTF-8
7Content-Transfer-Encoding: 8bit
8
9While the C API entry points will validate non-negative lengths
10for various parameters, the RPC server de-serialization code
11will need to allocate memory for arrays before entering the C
12API. These allocations will thus happen before the non-negative
13length check is performed.
14
15Passing a negative length to the g_new0 function will usually
16result in a crash due to the negative length being treated as
17a huge positive number.
18
19This was found and diagnosed by ALT Linux Team with AFLplusplus.
20
21CVE-2024-2494
22Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
23Found-by: Alexandr Shashkin <dutyrok@altlinux.org>
24Co-developed-by: Alexander Kuznetsov <kuznetsovam@altlinux.org>
25Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
26
27Upstream-Status: Backport [https://gitlab.com/libvirt/libvirt/-/commit/8a3f8d957507c1f8223fdcf25a3ff885b15557f2]
28CVE: CVE-2024-2494
29Signed-off-by: Hitendra Prajapati <hprajapati@mvista.com>
30---
31 src/remote/remote_daemon_dispatch.c | 65 +++++++++++++++++++++++++++++
32 src/rpc/gendispatch.pl | 5 +++
33 2 files changed, 70 insertions(+)
34
35diff --git a/src/remote/remote_daemon_dispatch.c b/src/remote/remote_daemon_dispatch.c
36index 7daf503..7542caa 100644
37--- a/src/remote/remote_daemon_dispatch.c
38+++ b/src/remote/remote_daemon_dispatch.c
39@@ -2291,6 +2291,10 @@ remoteDispatchDomainGetSchedulerParameters(virNetServer *server G_GNUC_UNUSED,
40 if (!conn)
41 goto cleanup;
42
43+ if (args->nparams < 0) {
44+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("nparams must be non-negative"));
45+ goto cleanup;
46+ }
47 if (args->nparams > REMOTE_DOMAIN_SCHEDULER_PARAMETERS_MAX) {
48 virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("nparams too large"));
49 goto cleanup;
50@@ -2339,6 +2343,10 @@ remoteDispatchDomainGetSchedulerParametersFlags(virNetServer *server G_GNUC_UNUS
51 if (!conn)
52 goto cleanup;
53
54+ if (args->nparams < 0) {
55+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("nparams must be non-negative"));
56+ goto cleanup;
57+ }
58 if (args->nparams > REMOTE_DOMAIN_SCHEDULER_PARAMETERS_MAX) {
59 virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("nparams too large"));
60 goto cleanup;
61@@ -2497,6 +2505,10 @@ remoteDispatchDomainBlockStatsFlags(virNetServer *server G_GNUC_UNUSED,
62 goto cleanup;
63 flags = args->flags;
64
65+ if (args->nparams < 0) {
66+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("nparams must be non-negative"));
67+ goto cleanup;
68+ }
69 if (args->nparams > REMOTE_DOMAIN_BLOCK_STATS_PARAMETERS_MAX) {
70 virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("nparams too large"));
71 goto cleanup;
72@@ -2717,6 +2729,14 @@ remoteDispatchDomainGetVcpuPinInfo(virNetServer *server G_GNUC_UNUSED,
73 if (!(dom = get_nonnull_domain(conn, args->dom)))
74 goto cleanup;
75
76+ if (args->ncpumaps < 0) {
77+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("ncpumaps must be non-negative"));
78+ goto cleanup;
79+ }
80+ if (args->maplen < 0) {
81+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("maplen must be non-negative"));
82+ goto cleanup;
83+ }
84 if (args->ncpumaps > REMOTE_VCPUINFO_MAX) {
85 virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("ncpumaps > REMOTE_VCPUINFO_MAX"));
86 goto cleanup;
87@@ -2811,6 +2831,11 @@ remoteDispatchDomainGetEmulatorPinInfo(virNetServer *server G_GNUC_UNUSED,
88 if (!(dom = get_nonnull_domain(conn, args->dom)))
89 goto cleanup;
90
91+ if (args->maplen < 0) {
92+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("maplen must be non-negative"));
93+ goto cleanup;
94+ }
95+
96 /* Allocate buffers to take the results */
97 if (args->maplen > 0)
98 cpumaps = g_new0(unsigned char, args->maplen);
99@@ -2858,6 +2883,14 @@ remoteDispatchDomainGetVcpus(virNetServer *server G_GNUC_UNUSED,
100 if (!(dom = get_nonnull_domain(conn, args->dom)))
101 goto cleanup;
102
103+ if (args->maxinfo < 0) {
104+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("maxinfo must be non-negative"));
105+ goto cleanup;
106+ }
107+ if (args->maplen < 0) {
108+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("maxinfo must be non-negative"));
109+ goto cleanup;
110+ }
111 if (args->maxinfo > REMOTE_VCPUINFO_MAX) {
112 virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("maxinfo > REMOTE_VCPUINFO_MAX"));
113 goto cleanup;
114@@ -3096,6 +3129,10 @@ remoteDispatchDomainGetMemoryParameters(virNetServer *server G_GNUC_UNUSED,
115
116 flags = args->flags;
117
118+ if (args->nparams < 0) {
119+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("nparams must be non-negative"));
120+ goto cleanup;
121+ }
122 if (args->nparams > REMOTE_DOMAIN_MEMORY_PARAMETERS_MAX) {
123 virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("nparams too large"));
124 goto cleanup;
125@@ -3156,6 +3193,10 @@ remoteDispatchDomainGetNumaParameters(virNetServer *server G_GNUC_UNUSED,
126
127 flags = args->flags;
128
129+ if (args->nparams < 0) {
130+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("nparams must be non-negative"));
131+ goto cleanup;
132+ }
133 if (args->nparams > REMOTE_DOMAIN_NUMA_PARAMETERS_MAX) {
134 virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("nparams too large"));
135 goto cleanup;
136@@ -3216,6 +3257,10 @@ remoteDispatchDomainGetBlkioParameters(virNetServer *server G_GNUC_UNUSED,
137
138 flags = args->flags;
139
140+ if (args->nparams < 0) {
141+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("nparams must be non-negative"));
142+ goto cleanup;
143+ }
144 if (args->nparams > REMOTE_DOMAIN_BLKIO_PARAMETERS_MAX) {
145 virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("nparams too large"));
146 goto cleanup;
147@@ -3277,6 +3322,10 @@ remoteDispatchNodeGetCPUStats(virNetServer *server G_GNUC_UNUSED,
148
149 flags = args->flags;
150
151+ if (args->nparams < 0) {
152+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("nparams must be non-negative"));
153+ goto cleanup;
154+ }
155 if (args->nparams > REMOTE_NODE_CPU_STATS_MAX) {
156 virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("nparams too large"));
157 goto cleanup;
158@@ -3339,6 +3388,10 @@ remoteDispatchNodeGetMemoryStats(virNetServer *server G_GNUC_UNUSED,
159
160 flags = args->flags;
161
162+ if (args->nparams < 0) {
163+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("nparams must be non-negative"));
164+ goto cleanup;
165+ }
166 if (args->nparams > REMOTE_NODE_MEMORY_STATS_MAX) {
167 virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("nparams too large"));
168 goto cleanup;
169@@ -3514,6 +3567,10 @@ remoteDispatchDomainGetBlockIoTune(virNetServer *server G_GNUC_UNUSED,
170 if (!conn)
171 goto cleanup;
172
173+ if (args->nparams < 0) {
174+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("nparams must be non-negative"));
175+ goto cleanup;
176+ }
177 if (args->nparams > REMOTE_DOMAIN_BLOCK_IO_TUNE_PARAMETERS_MAX) {
178 virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("nparams too large"));
179 goto cleanup;
180@@ -5079,6 +5136,10 @@ remoteDispatchDomainGetInterfaceParameters(virNetServer *server G_GNUC_UNUSED,
181
182 flags = args->flags;
183
184+ if (args->nparams < 0) {
185+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("nparams must be non-negative"));
186+ goto cleanup;
187+ }
188 if (args->nparams > REMOTE_DOMAIN_INTERFACE_PARAMETERS_MAX) {
189 virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("nparams too large"));
190 goto cleanup;
191@@ -5299,6 +5360,10 @@ remoteDispatchNodeGetMemoryParameters(virNetServer *server G_GNUC_UNUSED,
192
193 flags = args->flags;
194
195+ if (args->nparams < 0) {
196+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("nparams must be non-negative"));
197+ goto cleanup;
198+ }
199 if (args->nparams > REMOTE_NODE_MEMORY_PARAMETERS_MAX) {
200 virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("nparams too large"));
201 goto cleanup;
202diff --git a/src/rpc/gendispatch.pl b/src/rpc/gendispatch.pl
203index ea46a9d..17abadc 100755
204--- a/src/rpc/gendispatch.pl
205+++ b/src/rpc/gendispatch.pl
206@@ -1070,6 +1070,11 @@ elsif ($mode eq "server") {
207 print "\n";
208
209 if ($single_ret_as_list) {
210+ print " if (args->$single_ret_list_max_var < 0) {\n";
211+ print " virReportError(VIR_ERR_RPC,\n";
212+ print " \"%s\", _(\"max$single_ret_list_name must be non-negative\"));\n";
213+ print " goto cleanup;\n";
214+ print " }\n";
215 print " if (args->$single_ret_list_max_var > $single_ret_list_max_define) {\n";
216 print " virReportError(VIR_ERR_RPC,\n";
217 print " \"%s\", _(\"max$single_ret_list_name > $single_ret_list_max_define\"));\n";
218--
2192.25.1
220
diff --git a/recipes-extended/libvirt/libvirt/CVE-2024-4418.patch b/recipes-extended/libvirt/libvirt/CVE-2024-4418.patch
new file mode 100644
index 00000000..81189abb
--- /dev/null
+++ b/recipes-extended/libvirt/libvirt/CVE-2024-4418.patch
@@ -0,0 +1,86 @@
1From 8074d64dc2eca846d6a61efe1a9b7428a0ce1dd1 Mon Sep 17 00:00:00 2001
2From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= <berrange@redhat.com>
3Date: Tue, 30 Apr 2024 11:51:15 +0100
4Subject: [PATCH] rpc: ensure temporary GSource is removed from client event
5 loop
6MIME-Version: 1.0
7Content-Type: text/plain; charset=UTF-8
8Content-Transfer-Encoding: 8bit
9
10Users are seeing periodic segfaults from libvirt client apps,
11especially thread heavy ones like virt-manager. A typical
12stack trace would end up in the virNetClientIOEventFD method,
13with illegal access to stale stack data. eg
14The root cause is a bad assumption in the virNetClientIOEventLoop
15method. This method is run by whichever thread currently owns the
16buck, and is responsible for handling I/O. Inside a for(;;) loop,
17this method creates a temporary GSource, adds it to the event loop
18and runs g_main_loop_run(). When I/O is ready, the GSource callback
19(virNetClientIOEventFD) will fire and call g_main_loop_quit(), and
20return G_SOURCE_REMOVE which results in the temporary GSource being
21destroyed. A g_autoptr() will then remove the last reference.
22
23What was overlooked, is that a second thread can come along and
24while it can't enter virNetClientIOEventLoop, it will register an
25idle source that uses virNetClientIOWakeup to interrupt the
26original thread's 'g_main_loop_run' call. When this happens the
27virNetClientIOEventFD callback never runs, and so the temporary
28GSource is not destroyed. The g_autoptr() will remove a reference,
29but by virtue of still being attached to the event context, there
30is an extra reference held causing GSource to be leaked. The
31next time 'g_main_loop_run' is called, the original GSource will
32trigger its callback, and access data that was allocated on the
33stack by the previous thread, and likely SEGV.
34
35To solve this, the thread calling 'g_main_loop_run' must call
36g_source_destroy, immediately upon return, to guarantee that
37the temporary GSource is removed.
38
39CVE-2024-4418
40Reviewed-by: Ján Tomko <jtomko@redhat.com>
41Reported-by: Martin Shirokov <shirokovmartin@gmail.com>
42Tested-by: Martin Shirokov <shirokovmartin@gmail.com>
43Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
44
45Upstream-Status: Backport [https://gitlab.com/libvirt/libvirt/-/commit/8074d64dc2eca846d6a61efe1a9b7428a0ce1dd1]
46CVE: CVE-2024-4418
47Signed-off-by: Hitendra Prajapati <hprajapati@mvista.com>
48---
49 src/rpc/virnetclient.c | 14 +++++++++++++-
50 1 file changed, 13 insertions(+), 1 deletion(-)
51
52diff --git a/src/rpc/virnetclient.c b/src/rpc/virnetclient.c
53index 68098b1..147b0d6 100644
54--- a/src/rpc/virnetclient.c
55+++ b/src/rpc/virnetclient.c
56@@ -1657,7 +1657,7 @@ static int virNetClientIOEventLoop(virNetClient *client,
57 #endif /* !WIN32 */
58 int timeout = -1;
59 virNetMessage *msg = NULL;
60- g_autoptr(GSource) G_GNUC_UNUSED source = NULL;
61+ g_autoptr(GSource) source = NULL;
62 GIOCondition ev = 0;
63 struct virNetClientIOEventData data = {
64 .client = client,
65@@ -1721,6 +1721,18 @@ static int virNetClientIOEventLoop(virNetClient *client,
66
67 g_main_loop_run(client->eventLoop);
68
69+ /*
70+ * If virNetClientIOEventFD ran, this GSource will already be
71+ * destroyed due to G_SOURCE_REMOVE. It is harmless to re-destroy
72+ * it, since we still own a reference.
73+ *
74+ * If virNetClientIOWakeup ran, it will have interrupted the
75+ * g_main_loop_run call, before virNetClientIOEventFD could
76+ * run, and thus the GSource is still registered, and we need
77+ * to destroy it since it is referencing stack memory for 'data'
78+ */
79+ g_source_destroy(source);
80+
81 #ifndef WIN32
82 ignore_value(pthread_sigmask(SIG_SETMASK, &oldmask, NULL));
83 #endif /* !WIN32 */
84--
852.25.1
86
diff --git a/recipes-extended/libvirt/libvirt_10.0.0.bb b/recipes-extended/libvirt/libvirt_10.0.0.bb
index 6b19b700..a33b6980 100644
--- a/recipes-extended/libvirt/libvirt_10.0.0.bb
+++ b/recipes-extended/libvirt/libvirt_10.0.0.bb
@@ -32,6 +32,9 @@ SRC_URI = "http://libvirt.org/sources/libvirt-${PV}.tar.xz;name=libvirt \
32 file://gnutls-helper.py \ 32 file://gnutls-helper.py \
33 file://0001-prevent-gendispatch.pl-generating-build-path-in-code.patch \ 33 file://0001-prevent-gendispatch.pl-generating-build-path-in-code.patch \
34 file://0001-messon.build-remove-build-path-information-to-avoid-.patch \ 34 file://0001-messon.build-remove-build-path-information-to-avoid-.patch \
35 file://CVE-2024-1441.patch \
36 file://CVE-2024-2494.patch \
37 file://CVE-2024-4418.patch \
35 " 38 "
36 39
37SRC_URI[libvirt.sha256sum] = "8ba2e72ec8bdd2418554a1474c42c35704c30174b7611eaf9a16544b71bcf00a" 40SRC_URI[libvirt.sha256sum] = "8ba2e72ec8bdd2418554a1474c42c35704c30174b7611eaf9a16544b71bcf00a"