]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
network: Introduce mutex for bridge name generation
authorMichal Privoznik <mprivozn@redhat.com>
Thu, 7 Jan 2021 14:51:02 +0000 (15:51 +0100)
committerMichal Privoznik <mprivozn@redhat.com>
Thu, 7 Jan 2021 19:26:08 +0000 (20:26 +0100)
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>
src/network/bridge_driver.c

index a7c5aade14a073c19c1a7f747a74455b0631b597..b7c604eaea9ac4f6ef330edb248eb687f6e9ecf0 100644 (file)
@@ -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:
  *
@@ -3115,20 +3117,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;
 }