Skip to content

Commit 14d8692

Browse files
authored
libvirt: Patch for CVE-2024-4418 (#9197)
1 parent 4b86ac1 commit 14d8692

2 files changed

Lines changed: 103 additions & 1 deletion

File tree

SPECS/libvirt/CVE-2024-4418.patch

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
From 8074d64dc2eca846d6a61efe1a9b7428a0ce1dd1 Mon Sep 17 00:00:00 2001
2+
From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= <berrange@redhat.com>
3+
Date: Tue, 30 Apr 2024 11:51:15 +0100
4+
Subject: [PATCH] rpc: ensure temporary GSource is removed from client event
5+
loop
6+
MIME-Version: 1.0
7+
Content-Type: text/plain; charset=UTF-8
8+
Content-Transfer-Encoding: 8bit
9+
10+
Users are seeing periodic segfaults from libvirt client apps,
11+
especially thread heavy ones like virt-manager. A typical
12+
stack trace would end up in the virNetClientIOEventFD method,
13+
with illegal access to stale stack data. eg
14+
15+
==238721==ERROR: AddressSanitizer: stack-use-after-return on address 0x75cd18709788 at pc 0x75cd3111f907 bp 0x75cd181ff550 sp 0x75cd181ff548
16+
WRITE of size 4 at 0x75cd18709788 thread T11
17+
#0 0x75cd3111f906 in virNetClientIOEventFD /usr/src/debug/libvirt/libvirt-10.2.0/build/../src/rpc/virnetclient.c:1634:15
18+
#1 0x75cd3210d198 (/usr/lib/libglib-2.0.so.0+0x5a198) (BuildId: 0a2311dfbbc6c215dc36f4b6bdd2b4b6fbae55a2)
19+
#2 0x75cd3216c3be (/usr/lib/libglib-2.0.so.0+0xb93be) (BuildId: 0a2311dfbbc6c215dc36f4b6bdd2b4b6fbae55a2)
20+
#3 0x75cd3210ddc6 in g_main_loop_run (/usr/lib/libglib-2.0.so.0+0x5adc6) (BuildId: 0a2311dfbbc6c215dc36f4b6bdd2b4b6fbae55a2)
21+
#4 0x75cd3111a47c in virNetClientIOEventLoop /usr/src/debug/libvirt/libvirt-10.2.0/build/../src/rpc/virnetclient.c:1722:9
22+
#5 0x75cd3111a47c in virNetClientIO /usr/src/debug/libvirt/libvirt-10.2.0/build/../src/rpc/virnetclient.c:2002:10
23+
#6 0x75cd3111a47c in virNetClientSendInternal /usr/src/debug/libvirt/libvirt-10.2.0/build/../src/rpc/virnetclient.c:2170:11
24+
#7 0x75cd311198a8 in virNetClientSendWithReply /usr/src/debug/libvirt/libvirt-10.2.0/build/../src/rpc/virnetclient.c:2198:11
25+
#8 0x75cd31111653 in virNetClientProgramCall /usr/src/debug/libvirt/libvirt-10.2.0/build/../src/rpc/virnetclientprogram.c:318:9
26+
#9 0x75cd31241c8f in callFull /usr/src/debug/libvirt/libvirt-10.2.0/build/../src/remote/remote_driver.c:6054:10
27+
#10 0x75cd31241c8f in call /usr/src/debug/libvirt/libvirt-10.2.0/build/../src/remote/remote_driver.c:6076:12
28+
#11 0x75cd31241c8f in remoteNetworkGetXMLDesc /usr/src/debug/libvirt/libvirt-10.2.0/build/src/remote/remote_client_bodies.h:5959:9
29+
#12 0x75cd31410ff7 in virNetworkGetXMLDesc /usr/src/debug/libvirt/libvirt-10.2.0/build/../src/libvirt-network.c:952:15
30+
31+
The root cause is a bad assumption in the virNetClientIOEventLoop
32+
method. This method is run by whichever thread currently owns the
33+
buck, and is responsible for handling I/O. Inside a for(;;) loop,
34+
this method creates a temporary GSource, adds it to the event loop
35+
and runs g_main_loop_run(). When I/O is ready, the GSource callback
36+
(virNetClientIOEventFD) will fire and call g_main_loop_quit(), and
37+
return G_SOURCE_REMOVE which results in the temporary GSource being
38+
destroyed. A g_autoptr() will then remove the last reference.
39+
40+
What was overlooked, is that a second thread can come along and
41+
while it can't enter virNetClientIOEventLoop, it will register an
42+
idle source that uses virNetClientIOWakeup to interrupt the
43+
original thread's 'g_main_loop_run' call. When this happens the
44+
virNetClientIOEventFD callback never runs, and so the temporary
45+
GSource is not destroyed. The g_autoptr() will remove a reference,
46+
but by virtue of still being attached to the event context, there
47+
is an extra reference held causing GSource to be leaked. The
48+
next time 'g_main_loop_run' is called, the original GSource will
49+
trigger its callback, and access data that was allocated on the
50+
stack by the previous thread, and likely SEGV.
51+
52+
To solve this, the thread calling 'g_main_loop_run' must call
53+
g_source_destroy, immediately upon return, to guarantee that
54+
the temporary GSource is removed.
55+
56+
CVE-2024-4418
57+
Reviewed-by: Ján Tomko <jtomko@redhat.com>
58+
Reported-by: Martin Shirokov <shirokovmartin@gmail.com>
59+
Tested-by: Martin Shirokov <shirokovmartin@gmail.com>
60+
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
61+
---
62+
src/rpc/virnetclient.c | 14 +++++++++++++-
63+
1 file changed, 13 insertions(+), 1 deletion(-)
64+
65+
diff --git a/src/rpc/virnetclient.c b/src/rpc/virnetclient.c
66+
index 68098b1c8d..147b0d661a 100644
67+
--- a/src/rpc/virnetclient.c
68+
+++ b/src/rpc/virnetclient.c
69+
@@ -1657,7 +1657,7 @@ static int virNetClientIOEventLoop(virNetClient *client,
70+
#endif /* !WIN32 */
71+
int timeout = -1;
72+
virNetMessage *msg = NULL;
73+
- g_autoptr(GSource) G_GNUC_UNUSED source = NULL;
74+
+ g_autoptr(GSource) source = NULL;
75+
GIOCondition ev = 0;
76+
struct virNetClientIOEventData data = {
77+
.client = client,
78+
@@ -1721,6 +1721,18 @@ static int virNetClientIOEventLoop(virNetClient *client,
79+
80+
g_main_loop_run(client->eventLoop);
81+
82+
+ /*
83+
+ * If virNetClientIOEventFD ran, this GSource will already be
84+
+ * destroyed due to G_SOURCE_REMOVE. It is harmless to re-destroy
85+
+ * it, since we still own a reference.
86+
+ *
87+
+ * If virNetClientIOWakeup ran, it will have interrupted the
88+
+ * g_main_loop_run call, before virNetClientIOEventFD could
89+
+ * run, and thus the GSource is still registered, and we need
90+
+ * to destroy it since it is referencing stack memory for 'data'
91+
+ */
92+
+ g_source_destroy(source);
93+
+
94+
#ifndef WIN32
95+
ignore_value(pthread_sigmask(SIG_SETMASK, &oldmask, NULL));
96+
#endif /* !WIN32 */
97+
--
98+
GitLab

SPECS/libvirt/libvirt.spec

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
Summary: Virtualization API library that supports KVM, QEMU, Xen, ESX etc
1010
Name: libvirt
1111
Version: 7.10.0
12-
Release: 9%{?dist}
12+
Release: 10%{?dist}
1313
License: LGPLv2+
1414
Vendor: Microsoft Corporation
1515
Distribution: Mariner
@@ -21,6 +21,7 @@ Patch1: CVE-2023-2700.patch
2121
Patch2: CVE-2024-1441.patch
2222
Patch3: CVE-2024-2496.patch
2323
Patch4: CVE-2024-2494.patch
24+
Patch5: CVE-2024-4418.patch
2425

2526
BuildRequires: audit-libs-devel
2627
BuildRequires: augeas
@@ -1058,6 +1059,9 @@ exit 0
10581059
%{_libdir}/libnss_libvirt_guest.so.2
10591060

10601061
%changelog
1062+
* Wed May 22 2024 Juan Camposeco <juanarturoc@microsoft.com> - 7.10.0-10
1063+
- Patch to address CVE-2024-4418
1064+
10611065
* Tue Apr 09 2024 Suresh Thelkar <sthelkar@microsoft.com> - 7.10.0-9
10621066
- Patch to address CVE-2024-2494
10631067

0 commit comments

Comments
 (0)