import CS libvirt-8.0.0-23.2.module_el8+1073+14d98f02

This commit is contained in:
eabdullin 2024-07-08 08:05:04 +00:00
parent ba8ac8bedf
commit daae142f13
3 changed files with 147 additions and 1 deletions

View File

@ -0,0 +1,101 @@
From b84d0a699f3976644d3090562ce62ede55335fbc Mon Sep 17 00:00:00 2001
Message-ID: <b84d0a699f3976644d3090562ce62ede55335fbc.1717684031.git.jdenemar@redhat.com>
From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= <berrange@redhat.com>
Date: Tue, 30 Apr 2024 11:51:15 +0100
Subject: [PATCH] rpc: ensure temporary GSource is removed from client event
loop
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Users are seeing periodic segfaults from libvirt client apps,
especially thread heavy ones like virt-manager. A typical
stack trace would end up in the virNetClientIOEventFD method,
with illegal access to stale stack data. eg
==238721==ERROR: AddressSanitizer: stack-use-after-return on address 0x75cd18709788 at pc 0x75cd3111f907 bp 0x75cd181ff550 sp 0x75cd181ff548
WRITE of size 4 at 0x75cd18709788 thread T11
#0 0x75cd3111f906 in virNetClientIOEventFD /usr/src/debug/libvirt/libvirt-10.2.0/build/../src/rpc/virnetclient.c:1634:15
#1 0x75cd3210d198 (/usr/lib/libglib-2.0.so.0+0x5a198) (BuildId: 0a2311dfbbc6c215dc36f4b6bdd2b4b6fbae55a2)
#2 0x75cd3216c3be (/usr/lib/libglib-2.0.so.0+0xb93be) (BuildId: 0a2311dfbbc6c215dc36f4b6bdd2b4b6fbae55a2)
#3 0x75cd3210ddc6 in g_main_loop_run (/usr/lib/libglib-2.0.so.0+0x5adc6) (BuildId: 0a2311dfbbc6c215dc36f4b6bdd2b4b6fbae55a2)
#4 0x75cd3111a47c in virNetClientIOEventLoop /usr/src/debug/libvirt/libvirt-10.2.0/build/../src/rpc/virnetclient.c:1722:9
#5 0x75cd3111a47c in virNetClientIO /usr/src/debug/libvirt/libvirt-10.2.0/build/../src/rpc/virnetclient.c:2002:10
#6 0x75cd3111a47c in virNetClientSendInternal /usr/src/debug/libvirt/libvirt-10.2.0/build/../src/rpc/virnetclient.c:2170:11
#7 0x75cd311198a8 in virNetClientSendWithReply /usr/src/debug/libvirt/libvirt-10.2.0/build/../src/rpc/virnetclient.c:2198:11
#8 0x75cd31111653 in virNetClientProgramCall /usr/src/debug/libvirt/libvirt-10.2.0/build/../src/rpc/virnetclientprogram.c:318:9
#9 0x75cd31241c8f in callFull /usr/src/debug/libvirt/libvirt-10.2.0/build/../src/remote/remote_driver.c:6054:10
#10 0x75cd31241c8f in call /usr/src/debug/libvirt/libvirt-10.2.0/build/../src/remote/remote_driver.c:6076:12
#11 0x75cd31241c8f in remoteNetworkGetXMLDesc /usr/src/debug/libvirt/libvirt-10.2.0/build/src/remote/remote_client_bodies.h:5959:9
#12 0x75cd31410ff7 in virNetworkGetXMLDesc /usr/src/debug/libvirt/libvirt-10.2.0/build/../src/libvirt-network.c:952:15
The root cause is a bad assumption in the virNetClientIOEventLoop
method. This method is run by whichever thread currently owns the
buck, and is responsible for handling I/O. Inside a for(;;) loop,
this method creates a temporary GSource, adds it to the event loop
and runs g_main_loop_run(). When I/O is ready, the GSource callback
(virNetClientIOEventFD) will fire and call g_main_loop_quit(), and
return G_SOURCE_REMOVE which results in the temporary GSource being
destroyed. A g_autoptr() will then remove the last reference.
What was overlooked, is that a second thread can come along and
while it can't enter virNetClientIOEventLoop, it will register an
idle source that uses virNetClientIOWakeup to interrupt the
original thread's 'g_main_loop_run' call. When this happens the
virNetClientIOEventFD callback never runs, and so the temporary
GSource is not destroyed. The g_autoptr() will remove a reference,
but by virtue of still being attached to the event context, there
is an extra reference held causing GSource to be leaked. The
next time 'g_main_loop_run' is called, the original GSource will
trigger its callback, and access data that was allocated on the
stack by the previous thread, and likely SEGV.
To solve this, the thread calling 'g_main_loop_run' must call
g_source_destroy, immediately upon return, to guarantee that
the temporary GSource is removed.
CVE-2024-4418
Reviewed-by: Ján Tomko <jtomko@redhat.com>
Reported-by: Martin Shirokov <shirokovmartin@gmail.com>
Tested-by: Martin Shirokov <shirokovmartin@gmail.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
(cherry picked from commit 8074d64dc2eca846d6a61efe1a9b7428a0ce1dd1)
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
---
src/rpc/virnetclient.c | 14 +++++++++++++-
1 file changed, 13 insertions(+), 1 deletion(-)
diff --git a/src/rpc/virnetclient.c b/src/rpc/virnetclient.c
index f526ad89ec..b9490072c3 100644
--- a/src/rpc/virnetclient.c
+++ b/src/rpc/virnetclient.c
@@ -1664,7 +1664,7 @@ static int virNetClientIOEventLoop(virNetClient *client,
#endif /* !WIN32 */
int timeout = -1;
virNetMessage *msg = NULL;
- g_autoptr(GSource) G_GNUC_UNUSED source = NULL;
+ g_autoptr(GSource) source = NULL;
GIOCondition ev = 0;
struct virNetClientIOEventData data = {
.client = client,
@@ -1728,6 +1728,18 @@ static int virNetClientIOEventLoop(virNetClient *client,
g_main_loop_run(client->eventLoop);
+ /*
+ * If virNetClientIOEventFD ran, this GSource will already be
+ * destroyed due to G_SOURCE_REMOVE. It is harmless to re-destroy
+ * it, since we still own a reference.
+ *
+ * If virNetClientIOWakeup ran, it will have interrupted the
+ * g_main_loop_run call, before virNetClientIOEventFD could
+ * run, and thus the GSource is still registered, and we need
+ * to destroy it since it is referencing stack memory for 'data'
+ */
+ g_source_destroy(source);
+
#ifndef WIN32
ignore_value(pthread_sigmask(SIG_SETMASK, &oldmask, NULL));
#endif /* !WIN32 */
--
2.45.1

View File

@ -0,0 +1,39 @@
From ffbae27bd15ae9475fd4f0e79b492a7e03bca93e Mon Sep 17 00:00:00 2001
Message-ID: <ffbae27bd15ae9475fd4f0e79b492a7e03bca93e.1717684031.git.jdenemar@redhat.com>
From: Jonathon Jongsma <jjongsma@redhat.com>
Date: Fri, 22 Sep 2023 14:23:10 -0500
Subject: [PATCH] util: Fix error return for virProcessKillPainfullyDelay()
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Commit 93af79fb removed a cleanup label in favor of returning error
values directly in certain cases. But the final return value was changed
from -1 to 0. If we get to the end of the function, that means that
we've waited for the process to exit but it still exists. So we should
return -1. The error message was still being set correctly, but we were
returning a success status (0).
Signed-off-by: Jonathon Jongsma <jjongsma@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
(cherry picked from commit 51a074e74c6ef2fb95e6f53d41315e3f1e00be77)
https://issues.redhat.com/browse/RHEL-36064
---
src/util/virprocess.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/util/virprocess.c b/src/util/virprocess.c
index b559a4257e..f3933a2d16 100644
--- a/src/util/virprocess.c
+++ b/src/util/virprocess.c
@@ -471,7 +471,7 @@ virProcessKillPainfullyDelay(pid_t pid, bool force, unsigned int extradelay, boo
_("Failed to terminate process %lld with SIG%s"),
(long long)pid, signame);
- return 0;
+ return -1;
}
--
2.45.1

View File

@ -210,7 +210,7 @@
Summary: Library providing a simple virtualization API Summary: Library providing a simple virtualization API
Name: libvirt Name: libvirt
Version: 8.0.0 Version: 8.0.0
Release: 23.1%{?dist}%{?extra_release} Release: 23.2%{?dist}%{?extra_release}
License: LGPLv2+ License: LGPLv2+
URL: https://libvirt.org/ URL: https://libvirt.org/
@ -319,6 +319,8 @@ Patch96: libvirt-nodedev-update-transient-mdevs.patch
Patch97: libvirt-lib-Set-up-cpuset-controller-for-restrictive-numatune.patch Patch97: libvirt-lib-Set-up-cpuset-controller-for-restrictive-numatune.patch
Patch98: libvirt-virnuma-Avoid-integer-overflow-in-virNumaGetPages.patch Patch98: libvirt-virnuma-Avoid-integer-overflow-in-virNumaGetPages.patch
Patch99: libvirt-remote-check-for-negative-array-lengths-before-allocation.patch Patch99: libvirt-remote-check-for-negative-array-lengths-before-allocation.patch
Patch100: libvirt-util-Fix-error-return-for-virProcessKillPainfullyDelay.patch
Patch101: libvirt-rpc-ensure-temporary-GSource-is-removed-from-client-event-loop.patch
Requires: libvirt-daemon = %{version}-%{release} Requires: libvirt-daemon = %{version}-%{release}
Requires: libvirt-daemon-config-network = %{version}-%{release} Requires: libvirt-daemon-config-network = %{version}-%{release}
@ -2198,6 +2200,10 @@ exit 0
%changelog %changelog
* Thu Jun 6 2024 Jiri Denemark <jdenemar@redhat.com> - 8.0.0-23.2.el8
- util: Fix error return for virProcessKillPainfullyDelay() (RHEL-36064)
- rpc: ensure temporary GSource is removed from client event loop (CVE-2024-4418)
* Tue Apr 9 2024 Jiri Denemark <jdenemar@redhat.com> - 8.0.0-23.1.el8 * Tue Apr 9 2024 Jiri Denemark <jdenemar@redhat.com> - 8.0.0-23.1.el8
- remote: check for negative array lengths before allocation (CVE-2024-2494) - remote: check for negative array lengths before allocation (CVE-2024-2494)