Skip to content

Commit

Permalink
Possible race on ingress programming
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Flavio Crisciani committed Jun 7, 2018
1 parent 3931ba4 commit 7bb62d0
Showing 1 changed file with 4 additions and 5 deletions.
9 changes: 4 additions & 5 deletions service_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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)

Expand Down Expand Up @@ -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
}
Expand All @@ -523,9 +524,7 @@ func plumbProxy(iPort *PortConfig, isDelete bool) error {
return err
}

ingressProxyMu.Lock()
ingressProxyTbl[portSpec] = l
ingressProxyMu.Unlock()

return nil
}
Expand Down

0 comments on commit 7bb62d0

Please sign in to comment.