-
Notifications
You must be signed in to change notification settings - Fork 1.9k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
app-emulation/libvirt: Backport fix for CVE-2024-2494
The fix made it into app-emulation/libvirt-10.2.0 release. Backport the fix into anything older. https://nvd.nist.gov/vuln/detail/CVE-2024-2494 Signed-off-by: Michal Privoznik <michal.privoznik@gmail.com>
- Loading branch information
Showing
5 changed files
with
226 additions
and
0 deletions.
There are no files selected for viewing
222 changes: 222 additions & 0 deletions
222
...n/libvirt/files/libvirt-10.2.0-remote-check-for-negative-array-lengths-before-alloc.patch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,222 @@ | ||
From 10fa5f6ba64b354b99b0f7b372e66e45bb4d9379 Mon Sep 17 00:00:00 2001 | ||
Message-ID: <10fa5f6ba64b354b99b0f7b372e66e45bb4d9379.1713033988.git.mprivozn@redhat.com> | ||
In-Reply-To: <2127032ed8cd49001465dc0dce9f842e13467bc2.1713033988.git.mprivozn@redhat.com> | ||
References: <2127032ed8cd49001465dc0dce9f842e13467bc2.1713033988.git.mprivozn@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 2/2] 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: Michal Privoznik <mprivozn@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 7daf503b51..7542caa952 100644 | ||
--- a/src/remote/remote_daemon_dispatch.c | ||
+++ b/src/remote/remote_daemon_dispatch.c | ||
@@ -2291,6 +2291,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; | ||
@@ -2339,6 +2343,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; | ||
@@ -2497,6 +2505,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; | ||
@@ -2717,6 +2729,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; | ||
@@ -2811,6 +2831,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); | ||
@@ -2858,6 +2883,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; | ||
@@ -3096,6 +3129,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; | ||
@@ -3156,6 +3193,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; | ||
@@ -3216,6 +3257,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; | ||
@@ -3277,6 +3322,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; | ||
@@ -3339,6 +3388,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; | ||
@@ -3514,6 +3567,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; | ||
@@ -5079,6 +5136,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; | ||
@@ -5299,6 +5360,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 fa45d15a92..294e21f8a1 100755 | ||
--- a/src/rpc/gendispatch.pl | ||
+++ b/src/rpc/gendispatch.pl | ||
@@ -1070,6 +1070,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.43.2 | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters