瀏覽代碼

daemon: Check if endpoint address is in allowed range

This issue wasn't caught on ContainerCreate or NetworkConnect (when
container wasn't started yet).

Signed-off-by: Albin Kerouanton <albinker@gmail.com>
Albin Kerouanton 1 年之前
父節點
當前提交
19c07198b6
共有 2 個文件被更改,包括 36 次插入28 次删除
  1. 31 23
      daemon/container_operations.go
  2. 5 5
      integration-cli/docker_cli_network_unix_test.go

+ 31 - 23
daemon/container_operations.go

@@ -610,34 +610,42 @@ func validateEndpointSettings(nw *libnetwork.Network, nwName string, epConfig *n
 	}
 	}
 
 
 	_, _, nwIPv4Configs, nwIPv6Configs := nw.IpamConfig()
 	_, _, nwIPv4Configs, nwIPv6Configs := nw.IpamConfig()
-	for _, s := range []struct {
-		ipConfigured  bool
-		subnetConfigs []*libnetwork.IpamConf
-	}{
-		{
-			ipConfigured:  len(ipamConfig.IPv4Address) > 0,
-			subnetConfigs: nwIPv4Configs,
-		},
-		{
-			ipConfigured:  len(ipamConfig.IPv6Address) > 0,
-			subnetConfigs: nwIPv6Configs,
-		},
-	} {
-		if s.ipConfigured {
-			foundSubnet := false
-			for _, cfg := range s.subnetConfigs {
-				if len(cfg.PreferredPool) > 0 {
-					foundSubnet = true
-					break
-				}
+	if err := validateEndpointIPAddress(nwIPv4Configs, ipamConfig.IPv4Address); err != nil {
+		errs = append(errs, err)
+	}
+	if err := validateEndpointIPAddress(nwIPv6Configs, ipamConfig.IPv6Address); err != nil {
+		errs = append(errs, err)
+	}
+
+	return multierror.Join(errs...)
+}
+
+func validateEndpointIPAddress(nwIPAMConfig []*libnetwork.IpamConf, epAddr string) error {
+	if epAddr == "" {
+		return nil
+	}
+
+	var customSubnet bool
+	parsedAddr := net.ParseIP(epAddr)
+	for _, conf := range nwIPAMConfig {
+		if conf.PreferredPool != "" {
+			customSubnet = true
+
+			_, allowedRange, _ := net.ParseCIDR(conf.PreferredPool)
+			if conf.SubPool != "" {
+				_, allowedRange, _ = net.ParseCIDR(conf.SubPool)
 			}
 			}
-			if !foundSubnet {
-				errs = append(errs, runconfig.ErrUnsupportedNetworkNoSubnetAndIP)
+
+			if allowedRange.Contains(parsedAddr) {
+				return nil
 			}
 			}
 		}
 		}
 	}
 	}
 
 
-	return multierror.Join(errs...)
+	if customSubnet {
+		return fmt.Errorf("no predefined subnet or ip-range contain the IP address: %s", epAddr)
+	}
+	return runconfig.ErrUnsupportedNetworkNoSubnetAndIP
 }
 }
 
 
 // cleanOperationalData resets the operational data from the passed endpoint settings
 // cleanOperationalData resets the operational data from the passed endpoint settings

+ 5 - 5
integration-cli/docker_cli_network_unix_test.go

@@ -1289,9 +1289,9 @@ func (s *DockerNetworkSuite) TestDockerNetworkConnectPreferredIP(c *testing.T) {
 	verifyIPAddresses(c, "c0", "n0", "172.28.99.88", "2001:db8:1234::9988")
 	verifyIPAddresses(c, "c0", "n0", "172.28.99.88", "2001:db8:1234::9988")
 
 
 	// connect the container to the second network specifying an ip addresses
 	// connect the container to the second network specifying an ip addresses
-	dockerCmd(c, "network", "connect", "--ip", "172.30.55.44", "--ip6", "2001:db8:abcd::5544", "n1", "c0")
-	verifyIPAddressConfig(c, "c0", "n1", "172.30.55.44", "2001:db8:abcd::5544")
-	verifyIPAddresses(c, "c0", "n1", "172.30.55.44", "2001:db8:abcd::5544")
+	dockerCmd(c, "network", "connect", "--ip", "172.30.5.44", "--ip6", "2001:db8:abcd::5544", "n1", "c0")
+	verifyIPAddressConfig(c, "c0", "n1", "172.30.5.44", "2001:db8:abcd::5544")
+	verifyIPAddresses(c, "c0", "n1", "172.30.5.44", "2001:db8:abcd::5544")
 
 
 	// Stop and restart the container
 	// Stop and restart the container
 	dockerCmd(c, "stop", "c0")
 	dockerCmd(c, "stop", "c0")
@@ -1300,8 +1300,8 @@ func (s *DockerNetworkSuite) TestDockerNetworkConnectPreferredIP(c *testing.T) {
 	// verify requested addresses are applied and configs are still there
 	// verify requested addresses are applied and configs are still there
 	verifyIPAddressConfig(c, "c0", "n0", "172.28.99.88", "2001:db8:1234::9988")
 	verifyIPAddressConfig(c, "c0", "n0", "172.28.99.88", "2001:db8:1234::9988")
 	verifyIPAddresses(c, "c0", "n0", "172.28.99.88", "2001:db8:1234::9988")
 	verifyIPAddresses(c, "c0", "n0", "172.28.99.88", "2001:db8:1234::9988")
-	verifyIPAddressConfig(c, "c0", "n1", "172.30.55.44", "2001:db8:abcd::5544")
-	verifyIPAddresses(c, "c0", "n1", "172.30.55.44", "2001:db8:abcd::5544")
+	verifyIPAddressConfig(c, "c0", "n1", "172.30.5.44", "2001:db8:abcd::5544")
+	verifyIPAddresses(c, "c0", "n1", "172.30.5.44", "2001:db8:abcd::5544")
 
 
 	// Still it should fail to connect to the default network with a specified IP (whatever ip)
 	// Still it should fail to connect to the default network with a specified IP (whatever ip)
 	out, _, err := dockerCmdWithError("network", "connect", "--ip", "172.21.55.44", "bridge", "c0")
 	out, _, err := dockerCmdWithError("network", "connect", "--ip", "172.21.55.44", "bridge", "c0")