Browse Source

Possible race on ingress programming

Make sure that iptables operations on ingress
are serialized.
Before 2 racing routines trying to create the ingress chain
were allowed and one was failing reporting the chain as
already existing.
The lock guarantees that this condition does not happen anymore

Signed-off-by: Flavio Crisciani <flavio.crisciani@docker.com>
Flavio Crisciani 7 years ago
parent
commit
3d2b2f1c7e
1 changed files with 4 additions and 5 deletions
  1. 4 5
      libnetwork/service_linux.go

+ 4 - 5
libnetwork/service_linux.go

@@ -279,7 +279,7 @@ const ingressChain = "DOCKER-INGRESS"
 
 var (
 	ingressOnce     sync.Once
-	ingressProxyMu  sync.Mutex
+	ingressMu       sync.Mutex // lock for operations on ingress
 	ingressProxyTbl = make(map[string]io.Closer)
 	portConfigMu    sync.Mutex
 	portConfigTbl   = make(map[PortConfig]int)
@@ -328,6 +328,9 @@ func programIngress(gwIP net.IP, ingressPorts []*PortConfig, isDelete bool) erro
 		addDelOpt = "-D"
 	}
 
+	ingressMu.Lock()
+	defer ingressMu.Unlock()
+
 	chainExists := iptables.ExistChain(ingressChain, iptables.Nat)
 	filterChainExists := iptables.ExistChain(ingressChain, iptables.Filter)
 
@@ -497,13 +500,11 @@ func plumbProxy(iPort *PortConfig, isDelete bool) error {
 
 	portSpec := fmt.Sprintf("%d/%s", iPort.PublishedPort, strings.ToLower(PortConfig_Protocol_name[int32(iPort.Protocol)]))
 	if isDelete {
-		ingressProxyMu.Lock()
 		if listener, ok := ingressProxyTbl[portSpec]; ok {
 			if listener != nil {
 				listener.Close()
 			}
 		}
-		ingressProxyMu.Unlock()
 
 		return nil
 	}
@@ -523,9 +524,7 @@ func plumbProxy(iPort *PortConfig, isDelete bool) error {
 		return err
 	}
 
-	ingressProxyMu.Lock()
 	ingressProxyTbl[portSpec] = l
-	ingressProxyMu.Unlock()
 
 	return nil
 }