Merge pull request #20526 from tiborvass/1.10.2-cherrypicks

1.10.2 cherrypicks
diff --git a/Dockerfile b/Dockerfile
index 4d2c63d..0015136 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -88,7 +88,7 @@
 
 # Install Go
 # IMPORTANT: If the version of Go is updated, the Windows to Linux CI machines
-#            will need updating, to avoid errors. Ping #docker-maintainers on IRC 
+#            will need updating, to avoid errors. Ping #docker-maintainers on IRC
 #            with a heads-up.
 ENV GO_VERSION 1.5.3
 RUN curl -fsSL "https://storage.googleapis.com/golang/go${GO_VERSION}.linux-amd64.tar.gz" \
@@ -168,7 +168,7 @@
 	&& rm -rf "$GOPATH"
 
 # Install notary server
-ENV NOTARY_VERSION docker-v1.10-5
+ENV NOTARY_VERSION docker-v1.10.2-1
 RUN set -x \
 	&& export GOPATH="$(mktemp -d)" \
 	&& git clone https://github.com/docker/notary.git "$GOPATH/src/github.com/docker/notary" \
diff --git a/Dockerfile.armhf b/Dockerfile.armhf
index 9fb485b..95212e1 100644
--- a/Dockerfile.armhf
+++ b/Dockerfile.armhf
@@ -145,7 +145,7 @@
 	&& rm -rf "$GOPATH"
 
 # Install notary server
-ENV NOTARY_VERSION docker-v1.10-5
+ENV NOTARY_VERSION docker-v1.10.2-1
 RUN set -x \
 	&& export GOPATH="$(mktemp -d)" \
 	&& git clone https://github.com/docker/notary.git "$GOPATH/src/github.com/docker/notary" \
diff --git a/Dockerfile.ppc64le b/Dockerfile.ppc64le
index 1c843b3..e31352f 100644
--- a/Dockerfile.ppc64le
+++ b/Dockerfile.ppc64le
@@ -116,7 +116,7 @@
 	&& rm -rf "$GOPATH"
 
 # Install notary server
-#ENV NOTARY_VERSION docker-v1.10-5
+#ENV NOTARY_VERSION docker-v1.10.2-1
 #RUN set -x \
 #	&& export GOPATH="$(mktemp -d)" \
 #	&& git clone https://github.com/docker/notary.git "$GOPATH/src/github.com/docker/notary" \
diff --git a/Dockerfile.s390x b/Dockerfile.s390x
index b58d908..b627ad3 100644
--- a/Dockerfile.s390x
+++ b/Dockerfile.s390x
@@ -116,7 +116,7 @@
 	&& rm -rf "$GOPATH"
 
 # Install notary server
-ENV NOTARY_VERSION docker-v1.10-5
+ENV NOTARY_VERSION docker-v1.10.2-1
 RUN set -x \
 	&& export GOPATH="$(mktemp -d)" \
 	&& git clone https://github.com/docker/notary.git "$GOPATH/src/github.com/docker/notary" \
diff --git a/hack/vendor.sh b/hack/vendor.sh
index 2424c3f..1cd1a38 100755
--- a/hack/vendor.sh
+++ b/hack/vendor.sh
@@ -27,7 +27,7 @@
 clone git github.com/imdario/mergo 0.2.1
 
 #get libnetwork packages
-clone git github.com/docker/libnetwork v0.6.1-rc3
+clone git github.com/docker/libnetwork v0.6.2-rc.1
 clone git github.com/armon/go-metrics eb0af217e5e9747e41dd5303755356b62d28e3ec
 clone git github.com/hashicorp/go-msgpack 71c2886f5a673a35f909803f38ece5810165097b
 clone git github.com/hashicorp/memberlist 9a1e242e454d2443df330bdd51a436d5a9058fc4
@@ -50,14 +50,14 @@
 clone git github.com/vbatts/tar-split v0.9.11
 
 # get desired notary commit, might also need to be updated in Dockerfile
-clone git github.com/docker/notary docker-v1.10-5
+clone git github.com/docker/notary docker-v1.10.2-1
 
 clone git google.golang.org/grpc 174192fc93efcb188fc8f46ca447f0da606b6885 https://github.com/grpc/grpc-go.git
 clone git github.com/miekg/pkcs11 80f102b5cac759de406949c47f0928b99bd64cdf
 clone git github.com/docker/go v1.5.1-1-1-gbaf439e
 clone git github.com/agl/ed25519 d2b94fd789ea21d12fac1a4443dd3a3f79cda72c
 
-clone git github.com/opencontainers/runc 3d8a20bb772defc28c355534d83486416d1719b4 # libcontainer
+clone git github.com/opencontainers/runc 27dd48f6919a9bf8c25b41e97ca12f6fa73f8f77 # libcontainer
 clone git github.com/seccomp/libseccomp-golang 1b506fc7c24eec5a3693cdcbed40d9c226cfc6a1
 # libcontainer deps (see src/github.com/opencontainers/runc/Godeps/Godeps.json)
 clone git github.com/coreos/go-systemd v4
diff --git a/integration-cli/docker_cli_network_unix_test.go b/integration-cli/docker_cli_network_unix_test.go
index fc59e85..24dd8a9 100644
--- a/integration-cli/docker_cli_network_unix_test.go
+++ b/integration-cli/docker_cli_network_unix_test.go
@@ -1375,6 +1375,14 @@
 	c.Assert(err, check.NotNil)
 }
 
+func (s *DockerSuite) TestEmbeddedDNSInvalidInput(c *check.C) {
+	testRequires(c, DaemonIsLinux, NotUserNamespace)
+	dockerCmd(c, "network", "create", "-d", "bridge", "nw1")
+
+	// Sending garbge to embedded DNS shouldn't crash the daemon
+	dockerCmd(c, "run", "-i", "--net=nw1", "--name=c1", "debian:jessie", "bash", "-c", "echo InvalidQuery > /dev/udp/127.0.0.11/53")
+}
+
 func (s *DockerSuite) TestDockerNetworkConnectFailsNoInspectChange(c *check.C) {
 	dockerCmd(c, "run", "-d", "--name=bb", "busybox", "top")
 	c.Assert(waitRun("bb"), check.IsNil)
diff --git a/pkg/filenotify/poller.go b/pkg/filenotify/poller.go
index 0d92afd..0ab4338 100644
--- a/pkg/filenotify/poller.go
+++ b/pkg/filenotify/poller.go
@@ -118,8 +118,10 @@
 		w.remove(name)
 		delete(w.watches, name)
 	}
-	close(w.events)
-	close(w.errors)
+	// channels will be closed by GC, we don't do it to avoid panic in send
+	// functions
+	// close(w.events)
+	// close(w.errors)
 	return nil
 }
 
diff --git a/pkg/filenotify/poller_test.go b/pkg/filenotify/poller_test.go
index 49e6e64..228cf58 100644
--- a/pkg/filenotify/poller_test.go
+++ b/pkg/filenotify/poller_test.go
@@ -89,24 +89,6 @@
 		t.Fatal(err)
 	}
 
-	select {
-	case _, open := <-w.Events():
-		if open {
-			t.Fatal("event chan should be closed")
-		}
-	default:
-		t.Fatal("event chan should be closed")
-	}
-
-	select {
-	case _, open := <-w.Errors():
-		if open {
-			t.Fatal("errors chan should be closed")
-		}
-	default:
-		t.Fatal("errors chan should be closed")
-	}
-
 	f, err := ioutil.TempFile("", "asdf")
 	if err != nil {
 		t.Fatal(err)
diff --git a/vendor/src/github.com/docker/libnetwork/CHANGELOG.md b/vendor/src/github.com/docker/libnetwork/CHANGELOG.md
index f10bf8f..3113a37 100644
--- a/vendor/src/github.com/docker/libnetwork/CHANGELOG.md
+++ b/vendor/src/github.com/docker/libnetwork/CHANGELOG.md
@@ -1,5 +1,8 @@
 # Changelog
 
+## 0.6.2-rc1 (2016-02-19)
+- Fixes https://github.com/docker/docker/issues/20350
+
 ## 0.6.1-rc3 (2016-02-11)
 - Fixes getNetworksFromStore to not fail on inconsistent network state
 
diff --git a/vendor/src/github.com/docker/libnetwork/resolver.go b/vendor/src/github.com/docker/libnetwork/resolver.go
index e0a5e49..dc72140 100644
--- a/vendor/src/github.com/docker/libnetwork/resolver.go
+++ b/vendor/src/github.com/docker/libnetwork/resolver.go
@@ -200,6 +200,9 @@
 		err  error
 	)
 
+	if query == nil || len(query.Question) == 0 {
+		return
+	}
 	name := query.Question[0].Name
 	if query.Question[0].Qtype == dns.TypeA {
 		resp, err = r.handleIPv4Query(name, query)
diff --git a/vendor/src/github.com/docker/notary/client/client.go b/vendor/src/github.com/docker/notary/client/client.go
index b383c94..a8ff637 100644
--- a/vendor/src/github.com/docker/notary/client/client.go
+++ b/vendor/src/github.com/docker/notary/client/client.go
@@ -9,6 +9,7 @@
 	"net/url"
 	"os"
 	"path/filepath"
+	"strings"
 	"time"
 
 	"github.com/Sirupsen/logrus"
@@ -451,11 +452,48 @@
 		roles = []string{data.CanonicalTargetsRole}
 	}
 	targets := make(map[string]*TargetWithRole)
+
 	for _, role := range roles {
+		var foundRole *data.Role
+		walkRoles := []*data.Role{}
+		if role == data.CanonicalTargetsRole {
+			foundRole = &data.Role{
+				Name:             data.CanonicalTargetsRole,
+				Paths:            []string{""},
+				PathHashPrefixes: []string{""},
+			}
+		}
+
+		walkRoles = append(walkRoles, r.tufRepo.Targets[data.CanonicalTargetsRole].Signed.Delegations.Roles...)
+		for len(walkRoles) > 0 && foundRole == nil {
+			currRole := walkRoles[0]
+			walkRoles = walkRoles[1:]
+			if currRole.Name == role {
+				foundRole = currRole
+				break
+			}
+			if strings.HasPrefix(role, currRole.Name+"/") {
+				targetMeta, ok := r.tufRepo.Targets[currRole.Name]
+				if !ok {
+					continue
+				}
+				for _, childRole := range targetMeta.Signed.Delegations.Roles {
+					restricted, err := data.Restrict(*currRole, *childRole)
+					if err == nil {
+						walkRoles = append(walkRoles, restricted)
+					}
+				}
+			}
+		}
+
+		if foundRole == nil {
+			continue
+		}
+
 		// we don't need to do anything special with removing role from
 		// roles because listSubtree always processes role and only excludes
 		// descendant delegations that appear in roles.
-		r.listSubtree(targets, role, roles...)
+		r.listSubtree(targets, foundRole, roles...)
 	}
 
 	var targetList []*TargetWithRole
@@ -466,29 +504,32 @@
 	return targetList, nil
 }
 
-func (r *NotaryRepository) listSubtree(targets map[string]*TargetWithRole, role string, exclude ...string) {
+func (r *NotaryRepository) listSubtree(targets map[string]*TargetWithRole, role *data.Role, exclude ...string) {
 	excl := make(map[string]bool)
 	for _, r := range exclude {
 		excl[r] = true
 	}
-	roles := []string{role}
+	roles := []*data.Role{role}
 	for len(roles) > 0 {
 		role = roles[0]
 		roles = roles[1:]
-		tgts, ok := r.tufRepo.Targets[role]
+		tgts, ok := r.tufRepo.Targets[role.Name]
 		if !ok {
 			// not every role has to exist
 			continue
 		}
 		for name, meta := range tgts.Signed.Targets {
-			if _, ok := targets[name]; !ok {
+			if _, ok := targets[name]; !ok && role.CheckPaths(name) {
 				targets[name] = &TargetWithRole{
-					Target: Target{Name: name, Hashes: meta.Hashes, Length: meta.Length}, Role: role}
+					Target: Target{Name: name, Hashes: meta.Hashes, Length: meta.Length}, Role: role.Name}
 			}
 		}
-		for _, d := range tgts.Signed.Delegations.Roles {
-			if !excl[d.Name] {
-				roles = append(roles, d.Name)
+		for _, child := range tgts.Signed.Delegations.Roles {
+			if !excl[child.Name] {
+				child, err := data.Restrict(*role, *child)
+				if err == nil {
+					roles = append(roles, child)
+				}
 			}
 		}
 	}
@@ -511,10 +552,47 @@
 		roles = append(roles, data.CanonicalTargetsRole)
 	}
 	for _, role := range roles {
-		meta, foundRole := c.TargetMeta(role, name, roles...)
+
+		var foundRole *data.Role
+		walkRoles := []*data.Role{}
+		if role == data.CanonicalTargetsRole {
+			foundRole = &data.Role{
+				Name:             data.CanonicalTargetsRole,
+				Paths:            []string{""},
+				PathHashPrefixes: []string{""},
+			}
+		}
+
+		walkRoles = append(walkRoles, r.tufRepo.Targets[data.CanonicalTargetsRole].Signed.Delegations.Roles...)
+		for len(walkRoles) > 0 && foundRole == nil {
+			currRole := walkRoles[0]
+			walkRoles = walkRoles[1:]
+			if currRole.Name == role {
+				foundRole = currRole
+				break
+			}
+			if strings.HasPrefix(role, currRole.Name+"/") {
+				targetMeta, ok := r.tufRepo.Targets[currRole.Name]
+				if !ok {
+					continue
+				}
+				for _, childRole := range targetMeta.Signed.Delegations.Roles {
+					restricted, err := data.Restrict(*currRole, *childRole)
+					if err == nil && restricted.CheckPaths(name) {
+						walkRoles = append(walkRoles, restricted)
+					}
+				}
+			}
+		}
+
+		if foundRole == nil {
+			continue
+		}
+
+		meta, ownerName := c.TargetMeta(foundRole, name, roles...)
 		if meta != nil {
 			return &TargetWithRole{
-				Target: Target{Name: name, Hashes: meta.Hashes, Length: meta.Length}, Role: foundRole}, nil
+				Target: Target{Name: name, Hashes: meta.Hashes, Length: meta.Length}, Role: ownerName}, nil
 		}
 	}
 	return nil, fmt.Errorf("No trust data for %s", name)
diff --git a/vendor/src/github.com/docker/notary/tuf/client/client.go b/vendor/src/github.com/docker/notary/tuf/client/client.go
index 0eaa8c8..7903855 100644
--- a/vendor/src/github.com/docker/notary/tuf/client/client.go
+++ b/vendor/src/github.com/docker/notary/tuf/client/client.go
@@ -526,39 +526,44 @@
 
 // TargetMeta ensures the repo is up to date. It assumes downloadTargets
 // has already downloaded all delegated roles
-func (c Client) TargetMeta(role, path string, excludeRoles ...string) (*data.FileMeta, string) {
+func (c Client) TargetMeta(role *data.Role, path string, excludeRoles ...string) (*data.FileMeta, string) {
 	excl := make(map[string]bool)
 	for _, r := range excludeRoles {
 		excl[r] = true
 	}
 
-	pathDigest := sha256.Sum256([]byte(path))
-	pathHex := hex.EncodeToString(pathDigest[:])
-
 	// FIFO list of targets delegations to inspect for target
-	roles := []string{role}
+	roles := []*data.Role{role}
 	var (
 		meta *data.FileMeta
-		curr string
+		curr *data.Role
 	)
 	for len(roles) > 0 {
 		// have to do these lines here because of order of execution in for statement
 		curr = roles[0]
 		roles = roles[1:]
 
-		meta = c.local.TargetMeta(curr, path)
+		meta = c.local.TargetMeta(curr.Name, path)
 		if meta != nil {
 			// we found the target!
-			return meta, curr
+			return meta, curr.Name
 		}
-		delegations := c.local.TargetDelegations(curr, path, pathHex)
-		for _, d := range delegations {
-			if !excl[d.Name] {
-				roles = append(roles, d.Name)
+		tgts, ok := c.local.Targets[curr.Name]
+		if !ok {
+			// not every role has to exist
+			continue
+		}
+
+		for _, child := range tgts.Signed.Delegations.Roles {
+			if !excl[child.Name] {
+				child, err := data.Restrict(*curr, *child)
+				if err == nil && child.CheckPaths(path) {
+					roles = append(roles, child)
+				}
 			}
 		}
 	}
-	return meta, ""
+	return nil, ""
 }
 
 // DownloadTarget downloads the target to dst from the remote
diff --git a/vendor/src/github.com/docker/notary/tuf/data/roles.go b/vendor/src/github.com/docker/notary/tuf/data/roles.go
index a505c92..94fc65e 100644
--- a/vendor/src/github.com/docker/notary/tuf/data/roles.go
+++ b/vendor/src/github.com/docker/notary/tuf/data/roles.go
@@ -2,10 +2,11 @@
 
 import (
 	"fmt"
-	"github.com/Sirupsen/logrus"
 	"path"
 	"regexp"
 	"strings"
+
+	"github.com/Sirupsen/logrus"
 )
 
 // Canonical base role names
@@ -244,3 +245,40 @@
 	}
 	return keep
 }
+
+// Restrict restricts the paths and path hash prefixes for the passed in delegation role,
+// returning a copy of the role with validated paths as if it was a direct child
+func Restrict(parent, child Role) (*Role, error) {
+	if path.Dir(child.Name) != parent.Name {
+		return nil, fmt.Errorf("%s is not a parent of %s", parent.Name, child.Name)
+	}
+	return &Role{
+		RootRole: child.RootRole,
+		Name:     child.Name,
+		Paths:    RestrictDelegationPathPrefixes(parent.Paths, child.Paths),
+	}, nil
+}
+
+// RestrictDelegationPathPrefixes returns the list of valid delegationPaths that are prefixed by parentPaths
+func RestrictDelegationPathPrefixes(parentPaths, delegationPaths []string) []string {
+	validPaths := []string{}
+	if len(delegationPaths) == 0 {
+		return validPaths
+	}
+
+	// Validate each individual delegation path
+	for _, delgPath := range delegationPaths {
+		isPrefixed := false
+		for _, parentPath := range parentPaths {
+			if strings.HasPrefix(delgPath, parentPath) {
+				isPrefixed = true
+				break
+			}
+		}
+		// If the delegation path did not match prefix against any parent path, it is not valid
+		if isPrefixed {
+			validPaths = append(validPaths, delgPath)
+		}
+	}
+	return validPaths
+}
diff --git a/vendor/src/github.com/docker/notary/tuf/tuf.go b/vendor/src/github.com/docker/notary/tuf/tuf.go
index 96ab7da..109dce7 100644
--- a/vendor/src/github.com/docker/notary/tuf/tuf.go
+++ b/vendor/src/github.com/docker/notary/tuf/tuf.go
@@ -459,6 +459,9 @@
 		tr.keysDB.AddKey(k)
 	}
 	for _, r := range s.Signed.Delegations.Roles {
+		if path.Dir(r.Name) != role || tr.keysDB.GetRole(r.Name) != nil {
+			continue
+		}
 		tr.keysDB.AddRole(r)
 	}
 	tr.Targets[role] = s
diff --git a/vendor/src/github.com/opencontainers/runc/libcontainer/cgroups/fs/apply_raw.go b/vendor/src/github.com/opencontainers/runc/libcontainer/cgroups/fs/apply_raw.go
index 7d2da2d..f92e202 100644
--- a/vendor/src/github.com/opencontainers/runc/libcontainer/cgroups/fs/apply_raw.go
+++ b/vendor/src/github.com/opencontainers/runc/libcontainer/cgroups/fs/apply_raw.go
@@ -29,6 +29,7 @@
 		&NetPrioGroup{},
 		&PerfEventGroup{},
 		&FreezerGroup{},
+		&NameGroup{GroupName: "name=systemd", Join: true},
 	}
 	CgroupProcesses  = "cgroup.procs"
 	HugePageSizes, _ = cgroups.GetHugePageSize()
diff --git a/vendor/src/github.com/opencontainers/runc/libcontainer/cgroups/fs/name.go b/vendor/src/github.com/opencontainers/runc/libcontainer/cgroups/fs/name.go
index 0e423f6..d8cf1d8 100644
--- a/vendor/src/github.com/opencontainers/runc/libcontainer/cgroups/fs/name.go
+++ b/vendor/src/github.com/opencontainers/runc/libcontainer/cgroups/fs/name.go
@@ -9,6 +9,7 @@
 
 type NameGroup struct {
 	GroupName string
+	Join      bool
 }
 
 func (s *NameGroup) Name() string {
@@ -16,6 +17,10 @@
 }
 
 func (s *NameGroup) Apply(d *cgroupData) error {
+	if s.Join {
+		// ignore errors if the named cgroup does not exist
+		d.join(s.GroupName)
+	}
 	return nil
 }
 
@@ -24,6 +29,9 @@
 }
 
 func (s *NameGroup) Remove(d *cgroupData) error {
+	if s.Join {
+		removePath(d.path(s.GroupName))
+	}
 	return nil
 }