Compare commits
10 Commits
edd98e1309
...
19b018f150
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
19b018f150 | ||
|
|
797062e4e0 | ||
|
|
96b8edaf60 | ||
|
|
d246bc1314 | ||
|
|
696f9590b9 | ||
|
|
cda990d1fd | ||
|
|
e0d5ff1d0d | ||
|
|
cdb25f413b | ||
|
|
fd0af4a92a | ||
|
|
a03e6f9210 |
89
interface-fix-udev_device_get_sysattr_value-return-v.patch
Normal file
89
interface-fix-udev_device_get_sysattr_value-return-v.patch
Normal file
@ -0,0 +1,89 @@
|
||||
From 0d5c04534f0e041e9923da1cb37a431ae0d463a8 Mon Sep 17 00:00:00 2001
|
||||
From: Dmitry Frolov <frolov@swemel.ru>
|
||||
Date: Tue, 12 Sep 2023 15:56:47 +0300
|
||||
Subject: [PATCH 8/8] interface: fix udev_device_get_sysattr_value return value
|
||||
check
|
||||
|
||||
Reviewing the code I found that return value of function
|
||||
udev_device_get_sysattr_value() is dereferenced without a check.
|
||||
udev_device_get_sysattr_value() may return NULL by number of reasons.
|
||||
|
||||
v2: VIR_DEBUG added, replaced STREQ(NULLSTR()) with STREQ_NULLABLE()
|
||||
v3: More checks added, to skip earlier. More verbose VIR_DEBUG.
|
||||
|
||||
Signed-off-by: Dmitry Frolov <frolov@swemel.ru>
|
||||
Reviewed-by: Martin Kletzander <mkletzan@redhat.com>
|
||||
---
|
||||
src/interface/interface_backend_udev.c | 26 +++++++++++++++++++-------
|
||||
1 file changed, 19 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/src/interface/interface_backend_udev.c b/src/interface/interface_backend_udev.c
|
||||
index dde88860d3..00eeee6cc4 100644
|
||||
--- a/src/interface/interface_backend_udev.c
|
||||
+++ b/src/interface/interface_backend_udev.c
|
||||
@@ -23,6 +23,7 @@
|
||||
#include <dirent.h>
|
||||
#include <libudev.h>
|
||||
|
||||
+#include "virlog.h"
|
||||
#include "virerror.h"
|
||||
#include "virfile.h"
|
||||
#include "datatypes.h"
|
||||
@@ -41,6 +42,8 @@
|
||||
|
||||
#define VIR_FROM_THIS VIR_FROM_INTERFACE
|
||||
|
||||
+VIR_LOG_INIT("interface.interface_backend_udev");
|
||||
+
|
||||
struct udev_iface_driver {
|
||||
struct udev *udev;
|
||||
/* pid file FD, ensures two copies of the driver can't use the same root */
|
||||
@@ -371,11 +374,20 @@ udevConnectListAllInterfaces(virConnectPtr conn,
|
||||
const char *macaddr;
|
||||
virInterfaceDefPtr def;
|
||||
|
||||
- path = udev_list_entry_get_name(dev_entry);
|
||||
- dev = udev_device_new_from_syspath(udev, path);
|
||||
- name = udev_device_get_sysname(dev);
|
||||
+ if (!(path = udev_list_entry_get_name(dev_entry))) {
|
||||
+ VIR_DEBUG("Skipping interface, path == NULL");
|
||||
+ continue;
|
||||
+ }
|
||||
+ if (!(dev = udev_device_new_from_syspath(udev, path))) {
|
||||
+ VIR_DEBUG("Skipping interface '%s', dev == NULL", path);
|
||||
+ continue;
|
||||
+ }
|
||||
+ if (!(name = udev_device_get_sysname(dev))) {
|
||||
+ VIR_DEBUG("Skipping interface '%s', name == NULL", path);
|
||||
+ continue;
|
||||
+ }
|
||||
macaddr = udev_device_get_sysattr_value(dev, "address");
|
||||
- status = STREQ(udev_device_get_sysattr_value(dev, "operstate"), "up");
|
||||
+ status = STREQ_NULLABLE(udev_device_get_sysattr_value(dev, "operstate"), "up");
|
||||
|
||||
def = udevGetMinimalDefForDevice(dev);
|
||||
if (!virConnectListAllInterfacesCheckACL(conn, def)) {
|
||||
@@ -1000,9 +1012,9 @@ udevGetIfaceDef(struct udev *udev, const char *name)
|
||||
|
||||
/* MTU */
|
||||
mtu_str = udev_device_get_sysattr_value(dev, "mtu");
|
||||
- if (virStrToLong_ui(mtu_str, NULL, 10, &mtu) < 0) {
|
||||
+ if (!mtu_str || virStrToLong_ui(mtu_str, NULL, 10, &mtu) < 0) {
|
||||
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||
- _("Could not parse MTU value '%s'"), mtu_str);
|
||||
+ _("Could not parse MTU value '%s'"), NULLSTR(mtu_str));
|
||||
goto error;
|
||||
}
|
||||
ifacedef->mtu = mtu;
|
||||
@@ -1129,7 +1141,7 @@ udevInterfaceIsActive(virInterfacePtr ifinfo)
|
||||
goto cleanup;
|
||||
|
||||
/* Check if it's active or not */
|
||||
- status = STREQ(udev_device_get_sysattr_value(dev, "operstate"), "up");
|
||||
+ status = STREQ_NULLABLE(udev_device_get_sysattr_value(dev, "operstate"), "up");
|
||||
|
||||
udev_device_unref(dev);
|
||||
|
||||
--
|
||||
2.27.0
|
||||
|
||||
30
libvirt.spec
30
libvirt.spec
@ -101,7 +101,7 @@
|
||||
Summary: Library providing a simple virtualization API
|
||||
Name: libvirt
|
||||
Version: 6.2.0
|
||||
Release: 19
|
||||
Release: 25
|
||||
License: LGPLv2+
|
||||
URL: https://libvirt.org/
|
||||
|
||||
@ -154,6 +154,14 @@ Patch0041: virdevmapper-Don-t-cache-device-mapper-major.patch
|
||||
Patch0042: virdevmapper-Handle-kernel-without-device-mapper-sup.patch
|
||||
Patch0043: virsh-Display-vhostuser-socket-path-in-domblklist.patch
|
||||
Patch0044: nwfilter-fix-crash-when-counting-number-of-network-f.patch
|
||||
Patch0045: qemu-Add-missing-lock-in-qemuProcessHandleMonitorEOF.patch
|
||||
Patch0046: update-the-Chinese-translation-of-nwfilter.patch
|
||||
Patch0047: virsh-Fix-off-by-one-error-in-udevListInterfacesBySt.patch
|
||||
Patch0048: remote-check-for-negative-array-lengths-before-alloc.patch
|
||||
Patch0049: interface-fix-udev_device_get_sysattr_value-return-v.patch
|
||||
Patch0050: util-keep-track-of-full-GSource-object-not-source-ID.patch
|
||||
Patch0051: rpc-mark-source-returned-by-virEventGLibAddSocketWat.patch
|
||||
Patch0052: rpc-ensure-temporary-GSource-is-removed-from-client-.patch
|
||||
|
||||
Requires: libvirt-daemon = %{version}-%{release}
|
||||
Requires: libvirt-daemon-config-network = %{version}-%{release}
|
||||
@ -1888,6 +1896,26 @@ exit 0
|
||||
|
||||
|
||||
%changelog
|
||||
* Fri May 24 2024 jiangjiacheng <jiangjiacheng@huawei.com>
|
||||
- util: keep track of full GSource object not source ID number
|
||||
- rpc: mark source returned by virEventGLibAddSocketWatch as unused
|
||||
- rpc: ensure temporary GSource is removed from client event loop (CVE-2024-4418)
|
||||
|
||||
* Wed Apr 10 2024 caozhongwang <caozhongwang1@huawei.com>
|
||||
- interface: fix udev_device_get_sysattr_value return value check (CVE-2024-2496)
|
||||
|
||||
* Wed Apr 10 2024 caozhongwang <caozhongwang1@huawei.com>
|
||||
- remote: check for negative array lengths before allocation (CVE-2024-2494)
|
||||
|
||||
* Wed Apr 10 2024 caozhongwang <caozhongwang1@huawei.com>
|
||||
- vish:Fix off-by-one error in udevListInterfacesByStatus (CVE-2024-1441)
|
||||
|
||||
* Sat Dec 10 2022 yezengruan <yezengruan@huawei.com>
|
||||
- update the Chinese translation of nwfilter
|
||||
|
||||
* Thu Aug 25 2022 yezengruan <yezengruan@huawei.com>
|
||||
- qemu: Add missing lock in qemuProcessHandleMonitorEOF (CVE-2021-3975)
|
||||
|
||||
* Mon Jun 20 2022 yezengruan <yezengruan@huawei.com>
|
||||
- nwfilter: fix crash when counting number of network filters (CVE-2022-0897)
|
||||
|
||||
|
||||
38
qemu-Add-missing-lock-in-qemuProcessHandleMonitorEOF.patch
Normal file
38
qemu-Add-missing-lock-in-qemuProcessHandleMonitorEOF.patch
Normal file
@ -0,0 +1,38 @@
|
||||
From baaf85d9c8b304c6cc95a892fc23962e8175a817 Mon Sep 17 00:00:00 2001
|
||||
From: Peng Liang <liangpeng10@huawei.com>
|
||||
Date: Wed, 24 Feb 2021 19:28:23 +0800
|
||||
Subject: [PATCH] qemu: Add missing lock in qemuProcessHandleMonitorEOF
|
||||
|
||||
qemuMonitorUnregister will be called in multiple threads (e.g. threads
|
||||
in rpc worker pool and the vm event thread). In some cases, it isn't
|
||||
protected by the monitor lock, which may lead to call g_source_unref
|
||||
more than one time and a use-after-free problem eventually.
|
||||
|
||||
Add the missing lock in qemuProcessHandleMonitorEOF (which is the only
|
||||
position missing lock of monitor I found).
|
||||
|
||||
Suggested-by: Michal Privoznik <mprivozn@redhat.com>
|
||||
Signed-off-by: Peng Liang <liangpeng10@huawei.com>
|
||||
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
|
||||
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
|
||||
---
|
||||
src/qemu/qemu_process.c | 2 ++
|
||||
1 file changed, 2 insertions(+)
|
||||
|
||||
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
|
||||
index 6b9f6fb860..9701bb398b 100644
|
||||
--- a/src/qemu/qemu_process.c
|
||||
+++ b/src/qemu/qemu_process.c
|
||||
@@ -315,7 +315,9 @@ qemuProcessHandleMonitorEOF(qemuMonitorPtr mon,
|
||||
/* We don't want this EOF handler to be called over and over while the
|
||||
* thread is waiting for a job.
|
||||
*/
|
||||
+ virObjectLock(mon);
|
||||
qemuMonitorUnregister(mon);
|
||||
+ virObjectUnlock(mon);
|
||||
|
||||
/* We don't want any cleanup from EOF handler (or any other
|
||||
* thread) to enter qemu namespace. */
|
||||
--
|
||||
2.27.0
|
||||
|
||||
216
remote-check-for-negative-array-lengths-before-alloc.patch
Normal file
216
remote-check-for-negative-array-lengths-before-alloc.patch
Normal file
@ -0,0 +1,216 @@
|
||||
From e8245ba93fe1d7d345d10ff9a189b6f5188682b1 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= <berrange@redhat.com>
|
||||
Date: Fri, 15 Mar 2024 10:47:50 +0000
|
||||
Subject: [PATCH 7/8] 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.
|
||||
|
||||
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>
|
||||
---
|
||||
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 c5506c2e11..5a1a317452 100644
|
||||
--- a/src/remote/remote_daemon_dispatch.c
|
||||
+++ b/src/remote/remote_daemon_dispatch.c
|
||||
@@ -2307,6 +2307,10 @@ remoteDispatchDomainGetSchedulerParameters(virNetServerPtr 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;
|
||||
@@ -2355,6 +2359,10 @@ remoteDispatchDomainGetSchedulerParametersFlags(virNetServerPtr server G_GNUC_UN
|
||||
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;
|
||||
@@ -2516,6 +2524,10 @@ remoteDispatchDomainBlockStatsFlags(virNetServerPtr 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;
|
||||
@@ -2750,6 +2762,14 @@ remoteDispatchDomainGetVcpuPinInfo(virNetServerPtr 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;
|
||||
@@ -2845,6 +2865,11 @@ remoteDispatchDomainGetEmulatorPinInfo(virNetServerPtr 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 &&
|
||||
VIR_ALLOC_N(cpumaps, args->maplen) < 0)
|
||||
@@ -2893,6 +2918,14 @@ remoteDispatchDomainGetVcpus(virNetServerPtr 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;
|
||||
@@ -3140,6 +3173,10 @@ remoteDispatchDomainGetMemoryParameters(virNetServerPtr 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;
|
||||
@@ -3200,6 +3237,10 @@ remoteDispatchDomainGetNumaParameters(virNetServerPtr 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;
|
||||
@@ -3260,6 +3301,10 @@ remoteDispatchDomainGetBlkioParameters(virNetServerPtr 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;
|
||||
@@ -3321,6 +3366,10 @@ remoteDispatchNodeGetCPUStats(virNetServerPtr 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;
|
||||
@@ -3389,6 +3438,10 @@ remoteDispatchNodeGetMemoryStats(virNetServerPtr 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;
|
||||
@@ -3570,6 +3623,10 @@ remoteDispatchDomainGetBlockIoTune(virNetServerPtr 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;
|
||||
@@ -5128,6 +5185,10 @@ remoteDispatchDomainGetInterfaceParameters(virNetServerPtr 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;
|
||||
@@ -5350,6 +5411,10 @@ remoteDispatchNodeGetMemoryParameters(virNetServerPtr 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 590a46ef66..02612f1856 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.27.0
|
||||
|
||||
94
rpc-ensure-temporary-GSource-is-removed-from-client-.patch
Normal file
94
rpc-ensure-temporary-GSource-is-removed-from-client-.patch
Normal file
@ -0,0 +1,94 @@
|
||||
From 351dc443b1c6718b999cc40250ef0b210bcef118 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= <berrange@redhat.com>
|
||||
Date: Tue, 30 Apr 2024 11:51:15 +0100
|
||||
Subject: [PATCH 3/3] 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
|
||||
|
||||
==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>
|
||||
---
|
||||
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 f4bb537d50..969c624ae5 100644
|
||||
--- a/src/rpc/virnetclient.c
|
||||
+++ b/src/rpc/virnetclient.c
|
||||
@@ -1619,7 +1619,7 @@ static int virNetClientIOEventLoop(virNetClientPtr client,
|
||||
#endif /* !WIN32 */
|
||||
int timeout = -1;
|
||||
virNetMessagePtr msg = NULL;
|
||||
- g_autoptr(GSource) G_GNUC_UNUSED source = NULL;
|
||||
+ g_autoptr(GSource) source = NULL;
|
||||
GIOCondition ev = 0;
|
||||
struct virNetClientIOEventData data = {
|
||||
.client = client,
|
||||
@@ -1683,6 +1683,18 @@ static int virNetClientIOEventLoop(virNetClientPtr 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.33.0
|
||||
|
||||
57
rpc-mark-source-returned-by-virEventGLibAddSocketWat.patch
Normal file
57
rpc-mark-source-returned-by-virEventGLibAddSocketWat.patch
Normal file
@ -0,0 +1,57 @@
|
||||
From 5ab53ff977e17d20b0bf01010f2c3168781a659e Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?J=C3=A1n=20Tomko?= <jtomko@redhat.com>
|
||||
Date: Fri, 3 Sep 2021 16:36:54 +0200
|
||||
Subject: [PATCH 2/3] rpc: mark source returned by virEventGLibAddSocketWatch
|
||||
as unused
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Two users of virEventGLibAddSocketWatch care about the GSource
|
||||
it returns.
|
||||
|
||||
The other three free it by assigning it to an autofreed variable.
|
||||
|
||||
Mark them with G_GNUC_UNUSED to make this obvious to the reader
|
||||
and the compiler.
|
||||
|
||||
Signed-off-by: Ján Tomko <jtomko@redhat.com>
|
||||
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
|
||||
---
|
||||
src/rpc/virnetclient.c | 6 +++---
|
||||
1 file changed, 3 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/src/rpc/virnetclient.c b/src/rpc/virnetclient.c
|
||||
index 0a413f0153..f4bb537d50 100644
|
||||
--- a/src/rpc/virnetclient.c
|
||||
+++ b/src/rpc/virnetclient.c
|
||||
@@ -826,7 +826,7 @@ virNetClientIOEventTLS(int fd,
|
||||
static gboolean
|
||||
virNetClientTLSHandshake(virNetClientPtr client)
|
||||
{
|
||||
- g_autoptr(GSource) source = NULL;
|
||||
+ g_autoptr(GSource) G_GNUC_UNUSED source = NULL;
|
||||
GIOCondition ev;
|
||||
int ret;
|
||||
|
||||
@@ -883,7 +883,7 @@ int virNetClientSetTLSSession(virNetClientPtr client,
|
||||
int ret;
|
||||
char buf[1];
|
||||
int len;
|
||||
- g_autoptr(GSource) source = NULL;
|
||||
+ g_autoptr(GSource) G_GNUC_UNUSED source = NULL;
|
||||
|
||||
#ifndef WIN32
|
||||
sigset_t oldmask, blockedsigs;
|
||||
@@ -1619,7 +1619,7 @@ static int virNetClientIOEventLoop(virNetClientPtr client,
|
||||
#endif /* !WIN32 */
|
||||
int timeout = -1;
|
||||
virNetMessagePtr msg = NULL;
|
||||
- g_autoptr(GSource) source = NULL;
|
||||
+ g_autoptr(GSource) G_GNUC_UNUSED source = NULL;
|
||||
GIOCondition ev = 0;
|
||||
struct virNetClientIOEventData data = {
|
||||
.client = client,
|
||||
--
|
||||
2.33.0
|
||||
|
||||
28
update-the-Chinese-translation-of-nwfilter.patch
Normal file
28
update-the-Chinese-translation-of-nwfilter.patch
Normal file
@ -0,0 +1,28 @@
|
||||
From 0af67000d77afbc4c843709d8119010957855660 Mon Sep 17 00:00:00 2001
|
||||
From: yezengruan <yezengruan@huawei.com>
|
||||
Date: Sat, 10 Dec 2022 15:00:48 +0800
|
||||
Subject: [PATCH] update the Chinese translation of nwfilter
|
||||
|
||||
commit e9fd6de8f from upstream.
|
||||
|
||||
Signed-off-by: yezengruan <yezengruan@huawei.com>
|
||||
---
|
||||
po/zh_CN.mini.po | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/po/zh_CN.mini.po b/po/zh_CN.mini.po
|
||||
index 3d588abcbe..cd899a429c 100644
|
||||
--- a/po/zh_CN.mini.po
|
||||
+++ b/po/zh_CN.mini.po
|
||||
@@ -18301,7 +18301,7 @@ msgid "nvram device is only supported for PPC64"
|
||||
msgstr "只为 PPC64 支持 nvram 设备"
|
||||
|
||||
msgid "nwfilter is in use"
|
||||
-msgstr "nwfilter 未使用"
|
||||
+msgstr "nwfilter 使用中"
|
||||
|
||||
msgid "occupied"
|
||||
msgstr "已占用"
|
||||
--
|
||||
2.27.0
|
||||
|
||||
303
util-keep-track-of-full-GSource-object-not-source-ID.patch
Normal file
303
util-keep-track-of-full-GSource-object-not-source-ID.patch
Normal file
@ -0,0 +1,303 @@
|
||||
From 4160ede0261dfccd8156721a22fa48d9cd3c448a Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= <berrange@redhat.com>
|
||||
Date: Tue, 28 Jul 2020 15:54:13 +0100
|
||||
Subject: [PATCH 1/3] util: keep track of full GSource object not source ID
|
||||
number
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
The source ID number is an alternative way to identify a source that has
|
||||
been added to a GMainContext. Internally when a source ID is given, glib
|
||||
will lookup the corresponding GSource and use that. The use of a source
|
||||
ID is racy in some cases though, because it is invalid to continue to
|
||||
use an ID number after the GSource has been removed. It is thus safer
|
||||
to use the GSource object directly and have full control over the ref
|
||||
counting and thus cleanup.
|
||||
|
||||
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
|
||||
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
|
||||
---
|
||||
src/rpc/virnetclient.c | 27 +++++++------
|
||||
src/util/vireventglib.c | 73 +++++++++++++++++++++++-------------
|
||||
src/util/vireventglibwatch.c | 19 ++++++----
|
||||
src/util/vireventglibwatch.h | 13 ++++---
|
||||
4 files changed, 79 insertions(+), 53 deletions(-)
|
||||
|
||||
diff --git a/src/rpc/virnetclient.c b/src/rpc/virnetclient.c
|
||||
index 1c5bef86a1..0a413f0153 100644
|
||||
--- a/src/rpc/virnetclient.c
|
||||
+++ b/src/rpc/virnetclient.c
|
||||
@@ -826,6 +826,7 @@ virNetClientIOEventTLS(int fd,
|
||||
static gboolean
|
||||
virNetClientTLSHandshake(virNetClientPtr client)
|
||||
{
|
||||
+ g_autoptr(GSource) source = NULL;
|
||||
GIOCondition ev;
|
||||
int ret;
|
||||
|
||||
@@ -840,10 +841,10 @@ virNetClientTLSHandshake(virNetClientPtr client)
|
||||
else
|
||||
ev = G_IO_OUT;
|
||||
|
||||
- virEventGLibAddSocketWatch(virNetSocketGetFD(client->sock),
|
||||
- ev,
|
||||
- client->eventCtx,
|
||||
- virNetClientIOEventTLS, client, NULL);
|
||||
+ source = virEventGLibAddSocketWatch(virNetSocketGetFD(client->sock),
|
||||
+ ev,
|
||||
+ client->eventCtx,
|
||||
+ virNetClientIOEventTLS, client, NULL);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@@ -882,6 +883,7 @@ int virNetClientSetTLSSession(virNetClientPtr client,
|
||||
int ret;
|
||||
char buf[1];
|
||||
int len;
|
||||
+ g_autoptr(GSource) source = NULL;
|
||||
|
||||
#ifndef WIN32
|
||||
sigset_t oldmask, blockedsigs;
|
||||
@@ -934,10 +936,10 @@ int virNetClientSetTLSSession(virNetClientPtr client,
|
||||
* etc. If we make the grade, it will send us a '\1' byte.
|
||||
*/
|
||||
|
||||
- virEventGLibAddSocketWatch(virNetSocketGetFD(client->sock),
|
||||
- G_IO_IN,
|
||||
- client->eventCtx,
|
||||
- virNetClientIOEventTLSConfirm, client, NULL);
|
||||
+ source = virEventGLibAddSocketWatch(virNetSocketGetFD(client->sock),
|
||||
+ G_IO_IN,
|
||||
+ client->eventCtx,
|
||||
+ virNetClientIOEventTLSConfirm, client, NULL);
|
||||
|
||||
#ifndef WIN32
|
||||
/* Block SIGWINCH from interrupting poll in curses programs */
|
||||
@@ -1617,6 +1619,7 @@ static int virNetClientIOEventLoop(virNetClientPtr client,
|
||||
#endif /* !WIN32 */
|
||||
int timeout = -1;
|
||||
virNetMessagePtr msg = NULL;
|
||||
+ g_autoptr(GSource) source = NULL;
|
||||
GIOCondition ev = 0;
|
||||
struct virNetClientIOEventData data = {
|
||||
.client = client,
|
||||
@@ -1651,10 +1654,10 @@ static int virNetClientIOEventLoop(virNetClientPtr client,
|
||||
if (client->nstreams)
|
||||
ev |= G_IO_IN;
|
||||
|
||||
- virEventGLibAddSocketWatch(virNetSocketGetFD(client->sock),
|
||||
- ev,
|
||||
- client->eventCtx,
|
||||
- virNetClientIOEventFD, &data, NULL);
|
||||
+ source = virEventGLibAddSocketWatch(virNetSocketGetFD(client->sock),
|
||||
+ ev,
|
||||
+ client->eventCtx,
|
||||
+ virNetClientIOEventFD, &data, NULL);
|
||||
|
||||
/* Release lock while poll'ing so other threads
|
||||
* can stuff themselves on the queue */
|
||||
diff --git a/src/util/vireventglib.c b/src/util/vireventglib.c
|
||||
index 803332a6f8..6e334b3398 100644
|
||||
--- a/src/util/vireventglib.c
|
||||
+++ b/src/util/vireventglib.c
|
||||
@@ -45,7 +45,7 @@ struct virEventGLibHandle
|
||||
int fd;
|
||||
int events;
|
||||
int removed;
|
||||
- guint source;
|
||||
+ GSource *source;
|
||||
virEventHandleCallback cb;
|
||||
void *opaque;
|
||||
virFreeCallback ff;
|
||||
@@ -56,7 +56,7 @@ struct virEventGLibTimeout
|
||||
int timer;
|
||||
int interval;
|
||||
int removed;
|
||||
- guint source;
|
||||
+ GSource *source;
|
||||
virEventTimeoutCallback cb;
|
||||
void *opaque;
|
||||
virFreeCallback ff;
|
||||
@@ -210,23 +210,25 @@ virEventGLibHandleUpdate(int watch,
|
||||
if (events == data->events)
|
||||
goto cleanup;
|
||||
|
||||
- if (data->source != 0) {
|
||||
- VIR_DEBUG("Removed old handle watch=%d", data->source);
|
||||
- g_source_remove(data->source);
|
||||
+ if (data->source != NULL) {
|
||||
+ VIR_DEBUG("Removed old handle source=%p", data->source);
|
||||
+ g_source_destroy(data->source);
|
||||
+ g_source_unref(data->source);
|
||||
}
|
||||
|
||||
data->source = virEventGLibAddSocketWatch(
|
||||
data->fd, cond, NULL, virEventGLibHandleDispatch, data, NULL);
|
||||
|
||||
data->events = events;
|
||||
- VIR_DEBUG("Added new handle watch=%d", data->source);
|
||||
+ VIR_DEBUG("Added new handle source=%p", data->source);
|
||||
} else {
|
||||
- if (data->source == 0)
|
||||
+ if (data->source == NULL)
|
||||
goto cleanup;
|
||||
|
||||
- VIR_DEBUG("Removed old handle watch=%d", data->source);
|
||||
- g_source_remove(data->source);
|
||||
- data->source = 0;
|
||||
+ VIR_DEBUG("Removed old handle source=%p", data->source);
|
||||
+ g_source_destroy(data->source);
|
||||
+ g_source_unref(data->source);
|
||||
+ data->source = NULL;
|
||||
data->events = 0;
|
||||
}
|
||||
|
||||
@@ -272,9 +274,10 @@ virEventGLibHandleRemove(int watch)
|
||||
VIR_DEBUG("Remove handle data=%p watch=%d fd=%d",
|
||||
data, watch, data->fd);
|
||||
|
||||
- if (data->source != 0) {
|
||||
- g_source_remove(data->source);
|
||||
- data->source = 0;
|
||||
+ if (data->source != NULL) {
|
||||
+ g_source_destroy(data->source);
|
||||
+ g_source_unref(data->source);
|
||||
+ data->source = NULL;
|
||||
data->events = 0;
|
||||
}
|
||||
|
||||
@@ -309,6 +312,22 @@ virEventGLibTimeoutDispatch(void *opaque)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
+
|
||||
+static GSource *
|
||||
+virEventGLibTimeoutCreate(int interval,
|
||||
+ struct virEventGLibTimeout *data)
|
||||
+{
|
||||
+ GSource *source = g_timeout_source_new(interval);
|
||||
+
|
||||
+ g_source_set_callback(source,
|
||||
+ virEventGLibTimeoutDispatch,
|
||||
+ data, NULL);
|
||||
+ g_source_attach(source, NULL);
|
||||
+
|
||||
+ return source;
|
||||
+}
|
||||
+
|
||||
+
|
||||
static int
|
||||
virEventGLibTimeoutAdd(int interval,
|
||||
virEventTimeoutCallback cb,
|
||||
@@ -327,9 +346,7 @@ virEventGLibTimeoutAdd(int interval,
|
||||
data->opaque = opaque;
|
||||
data->ff = ff;
|
||||
if (interval >= 0)
|
||||
- data->source = g_timeout_add(interval,
|
||||
- virEventGLibTimeoutDispatch,
|
||||
- data);
|
||||
+ data->source = virEventGLibTimeoutCreate(interval, data);
|
||||
|
||||
g_ptr_array_add(timeouts, data);
|
||||
|
||||
@@ -390,19 +407,20 @@ virEventGLibTimeoutUpdate(int timer,
|
||||
VIR_DEBUG("Update timeout data=%p timer=%d interval=%d ms", data, timer, interval);
|
||||
|
||||
if (interval >= 0) {
|
||||
- if (data->source != 0)
|
||||
- g_source_remove(data->source);
|
||||
+ if (data->source != NULL) {
|
||||
+ g_source_destroy(data->source);
|
||||
+ g_source_unref(data->source);
|
||||
+ }
|
||||
|
||||
data->interval = interval;
|
||||
- data->source = g_timeout_add(data->interval,
|
||||
- virEventGLibTimeoutDispatch,
|
||||
- data);
|
||||
+ data->source = virEventGLibTimeoutCreate(interval, data);
|
||||
} else {
|
||||
- if (data->source == 0)
|
||||
+ if (data->source == NULL)
|
||||
goto cleanup;
|
||||
|
||||
- g_source_remove(data->source);
|
||||
- data->source = 0;
|
||||
+ g_source_destroy(data->source);
|
||||
+ g_source_unref(data->source);
|
||||
+ data->source = NULL;
|
||||
}
|
||||
|
||||
cleanup:
|
||||
@@ -448,9 +466,10 @@ virEventGLibTimeoutRemove(int timer)
|
||||
VIR_DEBUG("Remove timeout data=%p timer=%d",
|
||||
data, timer);
|
||||
|
||||
- if (data->source != 0) {
|
||||
- g_source_remove(data->source);
|
||||
- data->source = 0;
|
||||
+ if (data->source != NULL) {
|
||||
+ g_source_destroy(data->source);
|
||||
+ g_source_unref(data->source);
|
||||
+ data->source = NULL;
|
||||
}
|
||||
|
||||
/* since the actual timeout deletion is done asynchronously, a timeoutUpdate call may
|
||||
diff --git a/src/util/vireventglibwatch.c b/src/util/vireventglibwatch.c
|
||||
index 178707f6b7..b7f3a8786a 100644
|
||||
--- a/src/util/vireventglibwatch.c
|
||||
+++ b/src/util/vireventglibwatch.c
|
||||
@@ -233,17 +233,20 @@ GSource *virEventGLibCreateSocketWatch(int fd,
|
||||
#endif /* WIN32 */
|
||||
|
||||
|
||||
-guint virEventGLibAddSocketWatch(int fd,
|
||||
- GIOCondition condition,
|
||||
- GMainContext *context,
|
||||
- virEventGLibSocketFunc func,
|
||||
- gpointer opaque,
|
||||
- GDestroyNotify notify)
|
||||
+GSource *
|
||||
+virEventGLibAddSocketWatch(int fd,
|
||||
+ GIOCondition condition,
|
||||
+ GMainContext *context,
|
||||
+ virEventGLibSocketFunc func,
|
||||
+ gpointer opaque,
|
||||
+ GDestroyNotify notify)
|
||||
{
|
||||
- g_autoptr(GSource) source = NULL;
|
||||
+ GSource *source = NULL;
|
||||
|
||||
source = virEventGLibCreateSocketWatch(fd, condition);
|
||||
g_source_set_callback(source, (GSourceFunc)func, opaque, notify);
|
||||
|
||||
- return g_source_attach(source, context);
|
||||
+ g_source_attach(source, context);
|
||||
+
|
||||
+ return source;
|
||||
}
|
||||
diff --git a/src/util/vireventglibwatch.h b/src/util/vireventglibwatch.h
|
||||
index 2f7e61cfba..f57be1f503 100644
|
||||
--- a/src/util/vireventglibwatch.h
|
||||
+++ b/src/util/vireventglibwatch.h
|
||||
@@ -40,9 +40,10 @@ typedef gboolean (*virEventGLibSocketFunc)(int fd,
|
||||
GIOCondition condition,
|
||||
gpointer data);
|
||||
|
||||
-guint virEventGLibAddSocketWatch(int fd,
|
||||
- GIOCondition condition,
|
||||
- GMainContext *context,
|
||||
- virEventGLibSocketFunc func,
|
||||
- gpointer opaque,
|
||||
- GDestroyNotify notify);
|
||||
+GSource *virEventGLibAddSocketWatch(int fd,
|
||||
+ GIOCondition condition,
|
||||
+ GMainContext *context,
|
||||
+ virEventGLibSocketFunc func,
|
||||
+ gpointer opaque,
|
||||
+ GDestroyNotify notify)
|
||||
+ G_GNUC_WARN_UNUSED_RESULT;
|
||||
--
|
||||
2.33.0
|
||||
|
||||
39
virsh-Fix-off-by-one-error-in-udevListInterfacesBySt.patch
Normal file
39
virsh-Fix-off-by-one-error-in-udevListInterfacesBySt.patch
Normal file
@ -0,0 +1,39 @@
|
||||
From 001ede185f96d359481495a4016fcd0cffb2e1b0 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Kletzander <mkletzan@redhat.com>
|
||||
Date: Tue, 27 Feb 2024 16:20:12 +0100
|
||||
Subject: [PATCH 6/8] virsh:Fix off-by-one error in udevListInterfacesByStatus
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Ever since this function was introduced in 2012 it could've tried
|
||||
filling in an extra interface name. That was made worse in 2019 when
|
||||
the caller functions started accepting NULL arrays of size 0.
|
||||
|
||||
This is assigned CVE-2024-1441.
|
||||
|
||||
Signed-off-by: Martin Kletzander <mkletzan@redhat.com>
|
||||
Reported-by: Alexander Kuznetsov <kuznetsovam@altlinux.org>
|
||||
Fixes: 5a33366f5c0b18c93d161bd144f9f079de4ac8ca
|
||||
Fixes: d6064e2759a24e0802f363e3a810dc5a7d7ebb15
|
||||
Reviewed-by: Ján Tomko <jtomko@redhat.com>
|
||||
---
|
||||
src/interface/interface_backend_udev.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/interface/interface_backend_udev.c b/src/interface/interface_backend_udev.c
|
||||
index e388f98536..dde88860d3 100644
|
||||
--- a/src/interface/interface_backend_udev.c
|
||||
+++ b/src/interface/interface_backend_udev.c
|
||||
@@ -221,7 +221,7 @@ udevListInterfacesByStatus(virConnectPtr conn,
|
||||
virInterfaceDefPtr def;
|
||||
|
||||
/* Ensure we won't exceed the size of our array */
|
||||
- if (count > names_len)
|
||||
+ if (count >= names_len)
|
||||
break;
|
||||
|
||||
path = udev_list_entry_get_name(dev_entry);
|
||||
--
|
||||
2.27.0
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user