libvirt-8.0.0-23.1.el8
- remote: check for negative array lengths before allocation (CVE-2024-2494) Resolves: RHEL-29514
This commit is contained in:
		
							parent
							
								
									9963e730f3
								
							
						
					
					
						commit
						c2a0160c23
					
				| @ -0,0 +1,218 @@ | ||||
| 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 | ||||
| @ -210,7 +210,7 @@ | ||||
| Summary: Library providing a simple virtualization API | ||||
| Name: libvirt | ||||
| Version: 8.0.0 | ||||
| Release: 23%{?dist}%{?extra_release} | ||||
| Release: 23.1%{?dist}%{?extra_release} | ||||
| License: LGPLv2+ | ||||
| URL: https://libvirt.org/ | ||||
| 
 | ||||
| @ -318,6 +318,7 @@ Patch95: libvirt-node_device_conf-Avoid-memleak-in-virNodeDeviceGetPCIVPDDynamic | ||||
| 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 | ||||
| 
 | ||||
| Requires: libvirt-daemon = %{version}-%{release} | ||||
| Requires: libvirt-daemon-config-network = %{version}-%{release} | ||||
| @ -2197,6 +2198,9 @@ exit 0 | ||||
| 
 | ||||
| 
 | ||||
| %changelog | ||||
| * 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) | ||||
| 
 | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user