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
|
Summary: Library providing a simple virtualization API
|
||||||
Name: libvirt
|
Name: libvirt
|
||||||
Version: 6.2.0
|
Version: 6.2.0
|
||||||
Release: 19
|
Release: 25
|
||||||
License: LGPLv2+
|
License: LGPLv2+
|
||||||
URL: https://libvirt.org/
|
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
|
Patch0042: virdevmapper-Handle-kernel-without-device-mapper-sup.patch
|
||||||
Patch0043: virsh-Display-vhostuser-socket-path-in-domblklist.patch
|
Patch0043: virsh-Display-vhostuser-socket-path-in-domblklist.patch
|
||||||
Patch0044: nwfilter-fix-crash-when-counting-number-of-network-f.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 = %{version}-%{release}
|
||||||
Requires: libvirt-daemon-config-network = %{version}-%{release}
|
Requires: libvirt-daemon-config-network = %{version}-%{release}
|
||||||
@ -1888,6 +1896,26 @@ exit 0
|
|||||||
|
|
||||||
|
|
||||||
%changelog
|
%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>
|
* Mon Jun 20 2022 yezengruan <yezengruan@huawei.com>
|
||||||
- nwfilter: fix crash when counting number of network filters (CVE-2022-0897)
|
- 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