From e90f75c9e91427aa6254a89a10c619a17e2be594 Mon Sep 17 00:00:00 2001 From: chenjiankun Date: Thu, 28 Mar 2024 17:16:11 +0800 Subject: [PATCH] docker: fix CVE-2024-29018 libnet: Don't forward to upstream resolvers on internal nw Commit cbc2a71 makes `connect` syscall fail fast when a container is only attached to an internal network. Thanks to that, if such a container tries to resolve an "external" domain, the embedded resolver returns an error immediately instead of waiting for a timeout. This commit makes sure the embedded resolver doesn't even try to forward to upstream servers. Conflict:libnetwork/resolver.go,sandbox_dns_unix.go Reference:https://github.com/moby/moby/commit/790c3039d0ca5ed86ecd099b4b571496607628bc --- .../vendor/github.com/docker/libnetwork/endpoint.go | 13 ++++++++++++- .../vendor/github.com/docker/libnetwork/resolver.go | 9 +++++++++ .../docker/libnetwork/sandbox_dns_unix.go | 6 +++++- 3 files changed, 26 insertions(+), 2 deletions(-) diff --git a/components/engine/vendor/github.com/docker/libnetwork/endpoint.go b/components/engine/vendor/github.com/docker/libnetwork/endpoint.go index 822f88bd3..914169199 100644 --- a/components/engine/vendor/github.com/docker/libnetwork/endpoint.go +++ b/components/engine/vendor/github.com/docker/libnetwork/endpoint.go @@ -550,7 +550,13 @@ func (ep *endpoint) sbJoin(sb *sandbox, options ...EndpointOption) (err error) { return sb.setupDefaultGW() } - moveExtConn := sb.getGatewayEndpoint() != extEp + currentExtEp := sb.getGatewayEndpoint() + // Enable upstream forwarding if the sandbox gained external connectivity. + if sb.resolver != nil { + sb.resolver.SetForwardingPolicy(currentExtEp != nil) + } + + moveExtConn := currentExtEp != extEp if moveExtConn { if extEp != nil { @@ -786,6 +792,11 @@ func (ep *endpoint) sbLeave(sb *sandbox, force bool, options ...EndpointOption) // New endpoint providing external connectivity for the sandbox extEp = sb.getGatewayEndpoint() + // Disable upstream forwarding if the sandbox lost external connectivity. + if sb.resolver != nil { + sb.resolver.SetForwardingPolicy(extEp != nil) + } + if moveExtConn && extEp != nil { logrus.Debugf("Programming external connectivity on endpoint %s (%s)", extEp.Name(), extEp.ID()) extN, err := extEp.getNetworkFromStore() diff --git a/components/engine/vendor/github.com/docker/libnetwork/resolver.go b/components/engine/vendor/github.com/docker/libnetwork/resolver.go index 04afe7a1d..0e44352d7 100644 --- a/components/engine/vendor/github.com/docker/libnetwork/resolver.go +++ b/components/engine/vendor/github.com/docker/libnetwork/resolver.go @@ -24,6 +24,9 @@ type Resolver interface { // SetupFunc() provides the setup function that should be run // in the container's network namespace. SetupFunc(int) func() + // SetForwardingPolicy re-configures the embedded DNS resolver to either enable or disable forwarding DNS queries to + // external servers. + SetForwardingPolicy(bool) // NameServer() returns the IP of the DNS resolver for the // containers. NameServer() string @@ -196,6 +199,12 @@ func (r *resolver) SetExtServers(extDNS []extDNSEntry) { } } +// SetForwardingPolicy re-configures the embedded DNS resolver to either enable or disable forwarding DNS queries to +// external servers. +func (r *resolver) SetForwardingPolicy(policy bool) { + r.proxyDNS = policy +} + func (r *resolver) NameServer() string { return r.listenAddress } diff --git a/components/engine/vendor/github.com/docker/libnetwork/sandbox_dns_unix.go b/components/engine/vendor/github.com/docker/libnetwork/sandbox_dns_unix.go index db1b66b19..484987a83 100644 --- a/components/engine/vendor/github.com/docker/libnetwork/sandbox_dns_unix.go +++ b/components/engine/vendor/github.com/docker/libnetwork/sandbox_dns_unix.go @@ -27,7 +27,11 @@ const ( func (sb *sandbox) startResolver(restore bool) { sb.resolverOnce.Do(func() { var err error - sb.resolver = NewResolver(resolverIPSandbox, true, sb.Key(), sb) + // The resolver is started with proxyDNS=false if the sandbox does not currently + // have a gateway. So, if the Sandbox is only connected to an 'internal' network, + // it will not forward DNS requests to external resolvers. The resolver's + // proxyDNS setting is then updated as network Endpoints are added/removed. + sb.resolver = NewResolver(resolverIPSandbox, sb.getGatewayEndpoint() != nil, sb.Key(), sb) defer func() { if err != nil { sb.resolver = nil -- 2.33.0