Compare commits

..

1 Commits

Author SHA1 Message Date
722e8085db Fix CVE-2023-2700 + bugfixes 2023-07-12 13:43:01 +00:00
16 changed files with 21 additions and 683 deletions

View File

@ -1,77 +0,0 @@
From 08ddc711a2e6d94a0fce55fec8e012a434655d2c Mon Sep 17 00:00:00 2001
Message-ID: <08ddc711a2e6d94a0fce55fec8e012a434655d2c.1690812875.git.jdenemar@redhat.com>
From: Michal Privoznik <mprivozn@redhat.com>
Date: Fri, 1 Apr 2022 14:30:05 +0200
Subject: [PATCH] lib: Set up cpuset controller for restrictive numatune
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
The aim of 'restrictive' numatune mode is to rely solely on
CGroups to have QEMU running on configured NUMA nodes. However,
we were never setting the cpuset controller when a domain was
starting up. We are doing so only when
virDomainSetNumaParameters() is called (aka live pinning).
This is obviously wrong. Fortunately, fix is simple as
'restrictive' is similar to 'strict' - every location where
VIR_DOMAIN_NUMATUNE_MEM_STRICT occurs can be audited and
VIR_DOMAIN_NUMATUNE_MEM_RESTRICTIVE case can be added.
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2070380
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
(cherry picked from commit 629282d8845407c1aff9a26f5dc026e15121f8cd)
Conflicts:
- src/ch/ch_process.c: The CH driver diverged because it's
unsupported downstream. Just drop the conflicting hunk from
there.
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2223464
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
---
src/lxc/lxc_controller.c | 3 ++-
src/qemu/qemu_process.c | 6 ++++--
2 files changed, 6 insertions(+), 3 deletions(-)
diff --git a/src/lxc/lxc_controller.c b/src/lxc/lxc_controller.c
index 3c930eaacd..6fd8373256 100644
--- a/src/lxc/lxc_controller.c
+++ b/src/lxc/lxc_controller.c
@@ -812,7 +812,8 @@ static int virLXCControllerSetupResourceLimits(virLXCController *ctrl)
virDomainNumatuneMemMode mode;
if (virDomainNumatuneGetMode(ctrl->def->numa, -1, &mode) == 0) {
- if (mode == VIR_DOMAIN_NUMATUNE_MEM_STRICT &&
+ if ((mode == VIR_DOMAIN_NUMATUNE_MEM_STRICT ||
+ mode == VIR_DOMAIN_NUMATUNE_MEM_RESTRICTIVE) &&
virCgroupControllerAvailable(VIR_CGROUP_CONTROLLER_CPUSET)) {
/* Use virNuma* API iff necessary. Once set and child is exec()-ed,
* there's no way for us to change it. Rely on cgroups (if available
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 0fb665bc82..73d54f01cd 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -2645,7 +2645,8 @@ qemuProcessSetupPid(virDomainObj *vm,
virCgroupHasController(priv->cgroup, VIR_CGROUP_CONTROLLER_CPUSET)) {
if (virDomainNumatuneGetMode(vm->def->numa, -1, &mem_mode) == 0 &&
- mem_mode == VIR_DOMAIN_NUMATUNE_MEM_STRICT &&
+ (mem_mode == VIR_DOMAIN_NUMATUNE_MEM_STRICT ||
+ mem_mode == VIR_DOMAIN_NUMATUNE_MEM_RESTRICTIVE) &&
virDomainNumatuneMaybeFormatNodeset(vm->def->numa,
priv->autoNodeset,
&mem_mask, -1) < 0)
@@ -3162,7 +3163,8 @@ static int qemuProcessHook(void *data)
goto cleanup;
if (virDomainNumatuneGetMode(h->vm->def->numa, -1, &mode) == 0) {
- if (mode == VIR_DOMAIN_NUMATUNE_MEM_STRICT &&
+ if ((mode == VIR_DOMAIN_NUMATUNE_MEM_STRICT ||
+ mode == VIR_DOMAIN_NUMATUNE_MEM_RESTRICTIVE) &&
h->cfg->cgroupControllers & (1 << VIR_CGROUP_CONTROLLER_CPUSET) &&
virCgroupControllerAvailable(VIR_CGROUP_CONTROLLER_CPUSET)) {
/* Use virNuma* API iff necessary. Once set and child is exec()-ed,
--
2.41.0

View File

@ -21,6 +21,7 @@ Reviewed-by: Peter Krempa <pkrempa@redhat.com>
(cherry picked from commit 64d32118540aca3d42bc5ee21c8b780cafe04bfa)
https://bugzilla.redhat.com/show_bug.cgi?id=CVE-2023-2700
Signed-off-by: Ján Tomko <jtomko@redhat.com>
Signed-off-by: David Sloboda <david.x.sloboda@oracle.com>
---
src/conf/node_device_conf.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)

View File

@ -1,79 +0,0 @@
From aebcc09c7060f6eace93821c6a782031cf107d85 Mon Sep 17 00:00:00 2001
Message-ID: <aebcc09c7060f6eace93821c6a782031cf107d85.1687452713.git.jdenemar@redhat.com>
From: Boris Fiuczynski <fiuczy@linux.ibm.com>
Date: Mon, 8 May 2023 19:10:46 +0200
Subject: [PATCH] nodedev: update transient mdevs
Instead of updating defined mdevs only add another update for active
devices as well to cover transient mdev devices as well.
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2143158
Signed-off-by: Boris Fiuczynski <fiuczy@linux.ibm.com>
Reviewed-by: Jonathon Jongsma <jjongsma@redhat.com>
Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=2143160
(cherry picked from commit 44a0f2f0c8ff5e78c238013ed297b8fce223ac5a)
Signed-off-by: Jonathon Jongsma <jjongsma@redhat.com>
---
src/node_device/node_device_driver.c | 31 ++++++++++++++++++++++++++++
1 file changed, 31 insertions(+)
diff --git a/src/node_device/node_device_driver.c b/src/node_device/node_device_driver.c
index e6ab4bb94c..943f6121a0 100644
--- a/src/node_device/node_device_driver.c
+++ b/src/node_device/node_device_driver.c
@@ -1651,6 +1651,24 @@ virMdevctlListDefined(virNodeDeviceDef ***devs, char **errmsg)
}
+static int
+virMdevctlListActive(virNodeDeviceDef ***devs, char **errmsg)
+{
+ int status;
+ g_autofree char *output = NULL;
+ g_autoptr(virCommand) cmd = nodeDeviceGetMdevctlListCommand(false, &output, errmsg);
+
+ if (virCommandRun(cmd, &status) < 0 || status != 0) {
+ return -1;
+ }
+
+ if (!output)
+ return -1;
+
+ return nodeDeviceParseMdevctlJSON(output, devs);
+}
+
+
typedef struct _virMdevctlForEachData virMdevctlForEachData;
struct _virMdevctlForEachData {
int ndefs;
@@ -1712,6 +1730,8 @@ int
nodeDeviceUpdateMediatedDevices(void)
{
g_autofree virNodeDeviceDef **defs = NULL;
+ g_autofree virNodeDeviceDef **act_defs = NULL;
+ int act_ndefs = 0;
g_autofree char *errmsg = NULL;
g_autofree char *mdevctl = NULL;
virMdevctlForEachData data = { 0, };
@@ -1738,6 +1758,17 @@ nodeDeviceUpdateMediatedDevices(void)
if (nodeDeviceUpdateMediatedDevice(defs[i]) < 0)
return -1;
+ /* Update active/transient mdev devices */
+ if ((act_ndefs = virMdevctlListActive(&act_defs, &errmsg)) < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("failed to query mdevs from mdevctl: %1$s"), errmsg);
+ return -1;
+ }
+
+ for (i = 0; i < act_ndefs; i++)
+ if (nodeDeviceUpdateMediatedDevice(act_defs[i]) < 0)
+ return -1;
+
return 0;
}
--
2.41.0

View File

@ -14,6 +14,7 @@ Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
(cherry picked from commit f9ae469a6ebb17e0990096e826f049c1c46cd760)
https://bugzilla.redhat.com/show_bug.cgi?id=2170472
Signed-off-by: David Sloboda <david.x.sloboda@oracle.com>
---
src/qemu/qemu_monitor.h | 14 --------------
src/qemu/qemu_monitor_json.c | 3 +++

View File

@ -15,6 +15,7 @@ Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
(cherry picked from commit c5eb99a9d9af8683789e99cc904671e343580058)
https://bugzilla.redhat.com/show_bug.cgi?id=2170472
Signed-off-by: David Sloboda <david.x.sloboda@oracle.com>
---
src/qemu/qemu_monitor.h | 7 +------
1 file changed, 1 insertion(+), 6 deletions(-)

View File

@ -16,6 +16,7 @@ Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
(cherry picked from commit 7c35c483eaa78eb847e0865cbb210d5355f75d7a)
https://bugzilla.redhat.com/show_bug.cgi?id=2170472
Signed-off-by: David Sloboda <david.x.sloboda@oracle.com>
---
src/qemu/qemu_monitor.c | 50 ---------------------------------
src/qemu/qemu_monitor_priv.h | 54 ++++++++++++++++++++++++++++++++++++

View File

@ -19,6 +19,7 @@ Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
(cherry picked from commit b0e4ad5263c73a926b8246028c76c552b07fca74)
https://bugzilla.redhat.com/show_bug.cgi?id=2170472
Signed-off-by: David Sloboda <david.x.sloboda@oracle.com>
---
src/qemu/qemu_monitor.c | 4 +++-
src/qemu/qemu_monitor_priv.h | 2 ++

View File

@ -20,6 +20,7 @@ Reviewed-by: Ján Tomko <jtomko@redhat.com>
- qemuDomainObjEnter/ExitMonitor still needs 'driver'
https://bugzilla.redhat.com/show_bug.cgi?id=2170472
Signed-off-by: David Sloboda <david.x.sloboda@oracle.com>
---
src/qemu/qemu_block.c | 7 ++-----
1 file changed, 2 insertions(+), 5 deletions(-)

View File

@ -1,65 +0,0 @@
From e9418cec1ba24b6cf78f85bbbef8586ed612692a Mon Sep 17 00:00:00 2001
Message-Id: <e9418cec1ba24b6cf78f85bbbef8586ed612692a@dist-git>
From: =?UTF-8?q?J=C3=A1n=20Tomko?= <jtomko@redhat.com>
Date: Mon, 13 Mar 2023 13:56:47 +0100
Subject: [PATCH] qemu: relax shared memory check for vhostuser daemons
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
For some vhostuser daemons, we validate that the guest memory is shared
with the host.
With earlier versions of QEMU, it was only possible to mark memory
as shared by defining an explicit NUMA topology. Later, QEMU exposed
the name of the default memory backend (defaultRAMid) so we can mark
that memory as shared.
Since libvirt commit:
commit bff2ad5d6b1f25da02802273934d2a519159fec7
qemu: Relax validation for mem->access if guest has no NUMA
we already check for the case when user requests shared memory,
but QEMU did not expose defaultRAMid.
Drop the duplicit check from vhostuser device validation, to make
it pass on hotplug even after libvirtd restart.
This avoids the need to store the defaultRAMid, since we don't really
need it for anything after the VM has been already started.
https://bugzilla.redhat.com/show_bug.cgi?id=2078693
https://bugzilla.redhat.com/show_bug.cgi?id=2177701
Signed-off-by: Ján Tomko <jtomko@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
(cherry picked from commit d5c7b7870e45575f81fffcb611c2546d0e02e778)
Signed-off-by: Ján Tomko <jtomko@redhat.com>
---
src/qemu/qemu_validate.c | 8 ++------
1 file changed, 2 insertions(+), 6 deletions(-)
diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c
index 7bc14293d6..4069f47c12 100644
--- a/src/qemu/qemu_validate.c
+++ b/src/qemu/qemu_validate.c
@@ -1588,16 +1588,12 @@ qemuValidateDomainVirtioOptions(const virDomainVirtioOptions *virtio,
static int
qemuValidateDomainDefVhostUserRequireSharedMemory(const virDomainDef *def,
const char *name,
- virQEMUCaps *qemuCaps)
+ virQEMUCaps *qemuCaps G_GNUC_UNUSED)
{
- const char *defaultRAMId = virQEMUCapsGetMachineDefaultRAMid(qemuCaps,
- def->virtType,
- def->os.machine);
size_t numa_nodes = virDomainNumaGetNodeCount(def->numa);
size_t i;
- if (numa_nodes == 0 &&
- !(defaultRAMId && def->mem.access == VIR_DOMAIN_MEMORY_ACCESS_SHARED)) {
+ if (numa_nodes == 0 && def->mem.access != VIR_DOMAIN_MEMORY_ACCESS_SHARED) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("'%s' requires shared memory"), name);
return -1;
--
2.40.1

View File

@ -20,6 +20,7 @@ Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
(cherry picked from commit bbd4d4899391b3bd1906cce61a3634f42f4b1bdf)
https://bugzilla.redhat.com/show_bug.cgi?id=2170472
Signed-off-by: David Sloboda <david.x.sloboda@oracle.com>
---
src/qemu/qemu_monitor_json.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

View File

@ -1,218 +0,0 @@
From cb42cd98d347deeee7c225d8d1e9f71f232cad29 Mon Sep 17 00:00:00 2001
Message-ID: <cb42cd98d347deeee7c225d8d1e9f71f232cad29.1712647819.git.jdenemar@redhat.com>
From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= <berrange@redhat.com>
Date: Fri, 15 Mar 2024 10:47:50 +0000
Subject: [PATCH] remote: check for negative array lengths before allocation
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
While the C API entry points will validate non-negative lengths
for various parameters, the RPC server de-serialization code
will need to allocate memory for arrays before entering the C
API. These allocations will thus happen before the non-negative
length check is performed.
Passing a negative length to the g_new0 function will usually
result in a crash due to the negative length being treated as
a huge positive number.
This was found and diagnosed by ALT Linux Team with AFLplusplus.
CVE-2024-2494
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
Found-by: Alexandr Shashkin <dutyrok@altlinux.org>
Co-developed-by: Alexander Kuznetsov <kuznetsovam@altlinux.org>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
(cherry picked from commit 8a3f8d957507c1f8223fdcf25a3ff885b15557f2)
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
---
src/remote/remote_daemon_dispatch.c | 65 +++++++++++++++++++++++++++++
src/rpc/gendispatch.pl | 5 +++
2 files changed, 70 insertions(+)
diff --git a/src/remote/remote_daemon_dispatch.c b/src/remote/remote_daemon_dispatch.c
index 689001889e..c193227926 100644
--- a/src/remote/remote_daemon_dispatch.c
+++ b/src/remote/remote_daemon_dispatch.c
@@ -2306,6 +2306,10 @@ remoteDispatchDomainGetSchedulerParameters(virNetServer *server G_GNUC_UNUSED,
if (!conn)
goto cleanup;
+ if (args->nparams < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("nparams must be non-negative"));
+ goto cleanup;
+ }
if (args->nparams > REMOTE_DOMAIN_SCHEDULER_PARAMETERS_MAX) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("nparams too large"));
goto cleanup;
@@ -2354,6 +2358,10 @@ remoteDispatchDomainGetSchedulerParametersFlags(virNetServer *server G_GNUC_UNUS
if (!conn)
goto cleanup;
+ if (args->nparams < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("nparams must be non-negative"));
+ goto cleanup;
+ }
if (args->nparams > REMOTE_DOMAIN_SCHEDULER_PARAMETERS_MAX) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("nparams too large"));
goto cleanup;
@@ -2512,6 +2520,10 @@ remoteDispatchDomainBlockStatsFlags(virNetServer *server G_GNUC_UNUSED,
goto cleanup;
flags = args->flags;
+ if (args->nparams < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("nparams must be non-negative"));
+ goto cleanup;
+ }
if (args->nparams > REMOTE_DOMAIN_BLOCK_STATS_PARAMETERS_MAX) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("nparams too large"));
goto cleanup;
@@ -2737,6 +2749,14 @@ remoteDispatchDomainGetVcpuPinInfo(virNetServer *server G_GNUC_UNUSED,
if (!(dom = get_nonnull_domain(conn, args->dom)))
goto cleanup;
+ if (args->ncpumaps < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("ncpumaps must be non-negative"));
+ goto cleanup;
+ }
+ if (args->maplen < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("maplen must be non-negative"));
+ goto cleanup;
+ }
if (args->ncpumaps > REMOTE_VCPUINFO_MAX) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("ncpumaps > REMOTE_VCPUINFO_MAX"));
goto cleanup;
@@ -2831,6 +2851,11 @@ remoteDispatchDomainGetEmulatorPinInfo(virNetServer *server G_GNUC_UNUSED,
if (!(dom = get_nonnull_domain(conn, args->dom)))
goto cleanup;
+ if (args->maplen < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("maplen must be non-negative"));
+ goto cleanup;
+ }
+
/* Allocate buffers to take the results */
if (args->maplen > 0)
cpumaps = g_new0(unsigned char, args->maplen);
@@ -2878,6 +2903,14 @@ remoteDispatchDomainGetVcpus(virNetServer *server G_GNUC_UNUSED,
if (!(dom = get_nonnull_domain(conn, args->dom)))
goto cleanup;
+ if (args->maxinfo < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("maxinfo must be non-negative"));
+ goto cleanup;
+ }
+ if (args->maplen < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("maxinfo must be non-negative"));
+ goto cleanup;
+ }
if (args->maxinfo > REMOTE_VCPUINFO_MAX) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("maxinfo > REMOTE_VCPUINFO_MAX"));
goto cleanup;
@@ -3117,6 +3150,10 @@ remoteDispatchDomainGetMemoryParameters(virNetServer *server G_GNUC_UNUSED,
flags = args->flags;
+ if (args->nparams < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("nparams must be non-negative"));
+ goto cleanup;
+ }
if (args->nparams > REMOTE_DOMAIN_MEMORY_PARAMETERS_MAX) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("nparams too large"));
goto cleanup;
@@ -3177,6 +3214,10 @@ remoteDispatchDomainGetNumaParameters(virNetServer *server G_GNUC_UNUSED,
flags = args->flags;
+ if (args->nparams < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("nparams must be non-negative"));
+ goto cleanup;
+ }
if (args->nparams > REMOTE_DOMAIN_NUMA_PARAMETERS_MAX) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("nparams too large"));
goto cleanup;
@@ -3237,6 +3278,10 @@ remoteDispatchDomainGetBlkioParameters(virNetServer *server G_GNUC_UNUSED,
flags = args->flags;
+ if (args->nparams < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("nparams must be non-negative"));
+ goto cleanup;
+ }
if (args->nparams > REMOTE_DOMAIN_BLKIO_PARAMETERS_MAX) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("nparams too large"));
goto cleanup;
@@ -3298,6 +3343,10 @@ remoteDispatchNodeGetCPUStats(virNetServer *server G_GNUC_UNUSED,
flags = args->flags;
+ if (args->nparams < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("nparams must be non-negative"));
+ goto cleanup;
+ }
if (args->nparams > REMOTE_NODE_CPU_STATS_MAX) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("nparams too large"));
goto cleanup;
@@ -3365,6 +3414,10 @@ remoteDispatchNodeGetMemoryStats(virNetServer *server G_GNUC_UNUSED,
flags = args->flags;
+ if (args->nparams < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("nparams must be non-negative"));
+ goto cleanup;
+ }
if (args->nparams > REMOTE_NODE_MEMORY_STATS_MAX) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("nparams too large"));
goto cleanup;
@@ -3545,6 +3598,10 @@ remoteDispatchDomainGetBlockIoTune(virNetServer *server G_GNUC_UNUSED,
if (!conn)
goto cleanup;
+ if (args->nparams < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("nparams must be non-negative"));
+ goto cleanup;
+ }
if (args->nparams > REMOTE_DOMAIN_BLOCK_IO_TUNE_PARAMETERS_MAX) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("nparams too large"));
goto cleanup;
@@ -5087,6 +5144,10 @@ remoteDispatchDomainGetInterfaceParameters(virNetServer *server G_GNUC_UNUSED,
flags = args->flags;
+ if (args->nparams < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("nparams must be non-negative"));
+ goto cleanup;
+ }
if (args->nparams > REMOTE_DOMAIN_INTERFACE_PARAMETERS_MAX) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("nparams too large"));
goto cleanup;
@@ -5307,6 +5368,10 @@ remoteDispatchNodeGetMemoryParameters(virNetServer *server G_GNUC_UNUSED,
flags = args->flags;
+ if (args->nparams < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("nparams must be non-negative"));
+ goto cleanup;
+ }
if (args->nparams > REMOTE_NODE_MEMORY_PARAMETERS_MAX) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("nparams too large"));
goto cleanup;
diff --git a/src/rpc/gendispatch.pl b/src/rpc/gendispatch.pl
index 9f5bf0e316..aacab88808 100755
--- a/src/rpc/gendispatch.pl
+++ b/src/rpc/gendispatch.pl
@@ -1074,6 +1074,11 @@ elsif ($mode eq "server") {
print "\n";
if ($single_ret_as_list) {
+ print " if (args->$single_ret_list_max_var < 0) {\n";
+ print " virReportError(VIR_ERR_RPC,\n";
+ print " \"%s\", _(\"max$single_ret_list_name must be non-negative\"));\n";
+ print " goto cleanup;\n";
+ print " }\n";
print " if (args->$single_ret_list_max_var > $single_ret_list_max_define) {\n";
print " virReportError(VIR_ERR_RPC,\n";
print " \"%s\", _(\"max$single_ret_list_name > $single_ret_list_max_define\"));\n";
--
2.44.0

View File

@ -1,101 +0,0 @@
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

@ -1,39 +0,0 @@
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

@ -1,68 +0,0 @@
From f3ae3ac1807549c1eb4cc5a0286047ff019e14a0 Mon Sep 17 00:00:00 2001
Message-ID: <f3ae3ac1807549c1eb4cc5a0286047ff019e14a0.1702401900.git.jdenemar@redhat.com>
From: Michal Privoznik <mprivozn@redhat.com>
Date: Fri, 24 Nov 2023 11:59:32 +0100
Subject: [PATCH] virnuma: Avoid integer overflow in virNumaGetPages()
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
On systems with humongous pages (16GiB) and 32bit int it's easy
to hit integer overflow in virNumaGetPages(). What happens is,
inside of virNumaGetPages() as we process hugepages for given
NUMA node (e.g. in order to produce capabilities XML), we keep a
sum of sizes of pools in an ULL variable (huge_page_sum). In each
iteration, the variable is incremented by 1024 * page_size *
page_avail. Now, page_size is just an uint, so we have:
ULL += U * U * ULL;
and because of associativity, U * U is computed first and since
we have two operands of the same type, no type expansion happens.
But this means, for humongous pages (like 16GiB) the
multiplication overflows.
Therefore, move the multiplication out of the loop. This helps in
two ways:
1) now we have ULL += U * ULL; which expands the uint in
multiplication,
2) it saves couple of CPU cycles.
Resolves: https://issues.redhat.com/browse/RHEL-16749
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
(cherry picked from commit 9694d1ca6a4ef7a37ac20249eb8b85c1bb48ef6b)
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
---
src/util/virnuma.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/src/util/virnuma.c b/src/util/virnuma.c
index 7c892d6267..e0938867f9 100644
--- a/src/util/virnuma.c
+++ b/src/util/virnuma.c
@@ -806,9 +806,7 @@ virNumaGetPages(int node,
tmp_free[ntmp] = page_free;
ntmp++;
- /* page_size is in kibibytes while we want huge_page_sum
- * in just bytes. */
- huge_page_sum += 1024 * page_size * page_avail;
+ huge_page_sum += page_size * page_avail;
}
if (direrr < 0)
@@ -819,6 +817,9 @@ virNumaGetPages(int node,
VIR_REALLOC_N(tmp_avail, ntmp + 1);
VIR_REALLOC_N(tmp_free, ntmp + 1);
+ /* page_size is in kibibytes while we want huge_page_sum in just bytes. */
+ huge_page_sum *= 1024;
+
if (virNumaGetPageInfo(node, system_page_size, huge_page_sum,
&tmp_avail[ntmp], &tmp_free[ntmp]) < 0)
return -1;
--
2.43.0

View File

@ -36,6 +36,7 @@ https://bugzilla.redhat.com/show_bug.cgi?id=2196351
https://bugzilla.redhat.com/show_bug.cgi?id=CVE-2023-2700
Signed-off-by: Ján Tomko <jtomko@redhat.com>
Signed-off-by: David Sloboda <david.x.sloboda@oracle.com>
---
src/util/virpci.c | 1 +
1 file changed, 1 insertion(+)

View File

@ -210,7 +210,7 @@
Summary: Library providing a simple virtualization API
Name: libvirt
Version: 8.0.0
Release: 23.2%{?dist}%{?extra_release}
Release: 19.2%{?dist}%{?extra_release}.alma
License: LGPLv2+
URL: https://libvirt.org/
@ -306,21 +306,15 @@ Patch83: libvirt-vircpi-Add-PCIe-5.0-and-6.0-link-speeds.patch
Patch84: libvirt-conf-Make-VIR_DOMAIN_NET_TYPE_ETHERNET-not-share-host-view.patch
Patch85: libvirt-qemu-domain-Fix-logic-when-tainting-domain.patch
Patch86: libvirt-qemu-agent-Make-fetching-of-can-offline-member-from-guest-query-vcpus-optional.patch
# Patches taken from Oracle Linux libvirt-8.0.0-19.0.2.module+el8.8.0+21112+1cc1a24b.src.rpm
Patch87: libvirt-qemu-monitor-Drop-old-monitor-fields-from-struct-_qemuMonitorMessage.patch
Patch88: libvirt-qemu-Make-struct-_qemuMonitorMessage-private.patch
Patch89: libvirt-qemu-monitor-Move-declaration-of-struct-_qemuMonitor-to-qemu_monitor_priv.h.patch
Patch90: libvirt-qemu-qemuBlockGetNamedNodeData-Remove-pointless-error-path.patch
Patch91: libvirt-qemu-monitor-Store-whether-query-named-block-nodes-supports-flat-parameter.patch
Patch92: libvirt-qemuMonitorJSONBlockStatsUpdateCapacityBlockdev-Use-flat-mode-of-query-named-block-nodes.patch
Patch93: libvirt-qemu-relax-shared-memory-check-for-vhostuser-daemons.patch
Patch94: libvirt-virpci-Resolve-leak-in-virPCIVirtualFunctionList-cleanup.patch
Patch95: libvirt-node_device_conf-Avoid-memleak-in-virNodeDeviceGetPCIVPDDynamicCap.patch
Patch96: libvirt-nodedev-update-transient-mdevs.patch
Patch97: libvirt-lib-Set-up-cpuset-controller-for-restrictive-numatune.patch
Patch98: libvirt-virnuma-Avoid-integer-overflow-in-virNumaGetPages.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
Patch93: libvirt-virpci-Resolve-leak-in-virPCIVirtualFunctionList-cleanup.patch
Patch94: libvirt-node_device_conf-Avoid-memleak-in-virNodeDeviceGetPCIVPDDynamicCap.patch
Requires: libvirt-daemon = %{version}-%{release}
Requires: libvirt-daemon-config-network = %{version}-%{release}
@ -2200,32 +2194,15 @@ exit 0
%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
- remote: check for negative array lengths before allocation (CVE-2024-2494)
* Tue Dec 12 2023 Jiri Denemark <jdenemar@redhat.com> - 8.0.0-23
- virnuma: Avoid integer overflow in virNumaGetPages() (rhbz#RHEL-16749)
* Mon Jul 31 2023 Jiri Denemark <jdenemar@redhat.com> - 8.0.0-22
- lib: Set up cpuset controller for restrictive numatune (rhbz#2223464)
* Thu Jun 22 2023 Jiri Denemark <jdenemar@redhat.com> - 8.0.0-21
- nodedev: update transient mdevs (rhbz#2143160)
* Fri May 19 2023 Jiri Denemark <jdenemar@redhat.com> - 8.0.0-20
- qemu: monitor: Drop old monitor fields from 'struct _qemuMonitorMessage' (rhbz#2170472)
- qemu: Make 'struct _qemuMonitorMessage' private (rhbz#2170472)
- qemu: monitor: Move declaration of struct _qemuMonitor to qemu_monitor_priv.h (rhbz#2170472)
- qemu: qemuBlockGetNamedNodeData: Remove pointless error path (rhbz#2170472)
- qemu: monitor: Store whether 'query-named-block-nodes' supports 'flat' parameter (rhbz#2170472)
- qemuMonitorJSONBlockStatsUpdateCapacityBlockdev: Use 'flat' mode of query-named-block-nodes (rhbz#2170472)
- qemu: relax shared memory check for vhostuser daemons (rhbz#2177701)
- virpci: Resolve leak in virPCIVirtualFunctionList cleanup (CVE-2023-2700)
- node_device_conf: Avoid memleak in virNodeDeviceGetPCIVPDDynamicCap() (CVE-2023-2700)
* Wed Jul 12 2023 Andrew Lukoshko <alukoshko@almalinux.org> - 8.0.0-19.2.alma
- qemu: monitor: Drop old monitor fields from 'struct _qemuMonitorMessage'
- qemu: Make 'struct _qemuMonitorMessage' private
- qemu: monitor: Move declaration of struct _qemuMonitor to qemu_monitor_priv.h
- qemu: qemuBlockGetNamedNodeData: Remove pointless error path
- qemu: monitor: Store whether 'query-named-block-nodes' supports 'flat' parameter
- qemuMonitorJSONBlockStatsUpdateCapacityBlockdev: Use 'flat' mode of query-named-block-nodes
- virpci: Resolve leak in virPCIVirtualFunctionList cleanup [CVE-2023-2700]
- node_device_conf: Avoid memleak in virNodeDeviceGetPCIVPDDynamicCap() [CVE-2023-2700]
* Tue Mar 14 2023 Jiri Denemark <jdenemar@redhat.com> - 8.0.0-19
- qemu: domain: Fix logic when tainting domain (rhbz#2174447)