72 lines
2.3 KiB
Diff
72 lines
2.3 KiB
Diff
|
|
From b85da76baeebccdb35c12bbc16f82692c42a7372 Mon Sep 17 00:00:00 2001
|
||
|
|
From: Michal Privoznik <mprivozn@redhat.com>
|
||
|
|
Date: Thu, 7 Jan 2021 15:51:02 +0100
|
||
|
|
Subject: [PATCH 077/108] network: Introduce mutex for bridge name generation
|
||
|
|
|
||
|
|
When defining/creating a network the bridge name may be filled in
|
||
|
|
automatically by libvirt (if none provided in the input XML or
|
||
|
|
the one provided is a pattern, e.g. "virbr%d"). During the
|
||
|
|
bridge name generation process a candidate name is generated
|
||
|
|
which is then checked with the rest of already defined/running
|
||
|
|
networks for collisions.
|
||
|
|
|
||
|
|
Problem is, that there is no mutex guarding this critical section
|
||
|
|
and thus if two threads line up so that they both generate the
|
||
|
|
same candidate they won't find any collision and the same name is
|
||
|
|
then stored.
|
||
|
|
|
||
|
|
Resolves: https://gitlab.com/libvirt/libvirt/-/issues/78
|
||
|
|
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
|
||
|
|
Reviewed-by: Laine Stump <laine@redhat.com>
|
||
|
|
(cherry picked from commit ea0cfa115307ecb9fe05dd1953ec7ddd8dd39d72)
|
||
|
|
---
|
||
|
|
src/network/bridge_driver.c | 13 +++++++++++--
|
||
|
|
1 file changed, 11 insertions(+), 2 deletions(-)
|
||
|
|
|
||
|
|
diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c
|
||
|
|
index 21d02dd304..ce61ff483a 100644
|
||
|
|
--- a/src/network/bridge_driver.c
|
||
|
|
+++ b/src/network/bridge_driver.c
|
||
|
|
@@ -74,6 +74,8 @@
|
||
|
|
#define VIR_FROM_THIS VIR_FROM_NETWORK
|
||
|
|
#define MAX_BRIDGE_ID 256
|
||
|
|
|
||
|
|
+static virMutex bridgeNameValidateMutex = VIR_MUTEX_INITIALIZER;
|
||
|
|
+
|
||
|
|
/**
|
||
|
|
* VIR_NETWORK_DHCP_LEASE_FILE_SIZE_MAX:
|
||
|
|
*
|
||
|
|
@@ -3255,20 +3257,27 @@ static int
|
||
|
|
networkBridgeNameValidate(virNetworkObjListPtr nets,
|
||
|
|
virNetworkDefPtr def)
|
||
|
|
{
|
||
|
|
+ virMutexLock(&bridgeNameValidateMutex);
|
||
|
|
+
|
||
|
|
if (def->bridge && !strstr(def->bridge, "%d")) {
|
||
|
|
if (virNetworkObjBridgeInUse(nets, def->bridge, def->name)) {
|
||
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||
|
|
_("bridge name '%s' already in use."),
|
||
|
|
def->bridge);
|
||
|
|
- return -1;
|
||
|
|
+ goto error;
|
||
|
|
}
|
||
|
|
} else {
|
||
|
|
/* Allocate a bridge name */
|
||
|
|
if (networkFindUnusedBridgeName(nets, def) < 0)
|
||
|
|
- return -1;
|
||
|
|
+ goto error;
|
||
|
|
}
|
||
|
|
|
||
|
|
+ virMutexUnlock(&bridgeNameValidateMutex);
|
||
|
|
return 0;
|
||
|
|
+
|
||
|
|
+ error:
|
||
|
|
+ virMutexUnlock(&bridgeNameValidateMutex);
|
||
|
|
+ return -1;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
--
|
||
|
|
2.33.0
|
||
|
|
|