From 5a1b3e1c63239d346d481c27f3624f66397a0a0b Mon Sep 17 00:00:00 2001 Message-ID: <5a1b3e1c63239d346d481c27f3624f66397a0a0b.1787836581.git.jdenemar@redhat.com> From: Peter Krempa Date: Wed, 12 Aug 2026 16:51:58 +0200 Subject: [PATCH] remote: Fix integer overflow in RPC handler for virNodeGetFreePages (CVE-2026-18917) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit CVE-2026-18917 The RPC handler 'remoteDispatchNodeGetFreePages' multiplies the 'npages' argument with the 'cellcount' argument passed to 'virNodeGetFreePages', both of which are declared as 'unsigned int' to both do an RPC limit check against the 'REMOTE_NODE_MAX_CELLS' constant and then to allocate the memory to hold the result from the actual hypervisor driver. Since both the values are 'unsigned int' the product is also unsigned int so big enough numbers can overflow, both passing the check and also allocating not enough memory for the result. The hypervisor driver assumes that the passed buffer is large enough and overwrites memory. When this happens the the hypervisor daemon crashes. This can be triggered e.g. by passing 1023 and 4198405 as values which multiply to 1019 after wrapping to 32 bit unsigned value. Use the VIR_INT_MULTIPLY_OVERFLOW macro in the check to avoid the issue the same way as we do for other APIs doing multiplication of arguments to determine amount of required memory. Fixes: 34f2d0319d2098c77c8cc27d8350616029125a2b (v1.2.5-164-g34f2d0319d) Closes: https://gitlab.com/libvirt/libvirt/-/work_items/903 Signed-off-by: Peter Krempa Reviewed-by: Daniel P. Berrangé (cherry picked from commit 5a62cbf2907d4590283597b46da9c0f41e7b4d4f) https://redhat.atlassian.net/browse/RHEL-245273 --- src/remote/remote_daemon_dispatch.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/remote/remote_daemon_dispatch.c b/src/remote/remote_daemon_dispatch.c index 329853b6da..7e2b76a7ce 100644 --- a/src/remote/remote_daemon_dispatch.c +++ b/src/remote/remote_daemon_dispatch.c @@ -6723,13 +6723,14 @@ remoteDispatchNodeGetFreePages(virNetServer *server G_GNUC_UNUSED, if (!conn) goto cleanup; - if (args->pages.pages_len * args->cellCount > REMOTE_NODE_MAX_CELLS) { - virReportError(VIR_ERR_INTERNAL_ERROR, "%s", - _("the result won't fit into REMOTE_NODE_MAX_CELLS")); + if (VIR_INT_MULTIPLY_OVERFLOW(args->pages.pages_len, args->cellCount) || + args->pages.pages_len * args->cellCount > REMOTE_NODE_MAX_CELLS) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("npages * cellcount > REMOTE_NODE_MAX_CELLS (%1$u)"), + REMOTE_NODE_MAX_CELLS); goto cleanup; } - /* Allocate return buffer. */ ret->counts.counts_val = g_new0(uint64_t, args->pages.pages_len * args->cellCount); -- 2.55.0