import CS libvirt-8.0.0-23.2.module_el8+1073+14d98f02
This commit is contained in:
		
							parent
							
								
									ba8ac8bedf
								
							
						
					
					
						commit
						daae142f13
					
				| @ -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 | ||||||
| @ -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 | ||||||
| @ -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) | ||||||
| 
 | 
 | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user