Fix possible StackOverflowError when try to resolve authorative names… (#10337)

Motivation:

There is a possibility to end up with a StackOverflowError when trying to resolve authorative nameservers because of incorrect wrapping the AuthoritativeDnsServerCache.

Modifications:

Ensure we don't end up with an overflow due wrapping

Result:

Fixes https://github.com/netty/netty/issues/10246
This commit is contained in:
Norman Maurer 2020-06-04 17:56:59 +02:00 committed by GitHub
parent 21eb936dbe
commit 0bd8771697
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -498,12 +498,33 @@ abstract class DnsResolveContext<T> {
} }
} }
}); });
if (!DnsNameResolver.doResolveAllCached(nameServerName, additionals, resolverPromise, resolveCache(), DnsCache resolveCache = resolveCache();
if (!DnsNameResolver.doResolveAllCached(nameServerName, additionals, resolverPromise, resolveCache,
parent.resolvedInternetProtocolFamiliesUnsafe())) { parent.resolvedInternetProtocolFamiliesUnsafe())) {
final AuthoritativeDnsServerCache authoritativeDnsServerCache = authoritativeDnsServerCache();
new DnsAddressResolveContext(parent, originalPromise, nameServerName, additionals, new DnsAddressResolveContext(parent, originalPromise, nameServerName, additionals,
parent.newNameServerAddressStream(nameServerName), parent.newNameServerAddressStream(nameServerName), resolveCache,
resolveCache(), new AuthoritativeDnsServerCache() { redirectAuthoritativeDnsServerCache(authoritativeDnsServerCache()), false)
.resolve(resolverPromise);
}
}
private static AuthoritativeDnsServerCache redirectAuthoritativeDnsServerCache(
AuthoritativeDnsServerCache authoritativeDnsServerCache) {
// Don't wrap again to prevent the possibility of an StackOverflowError when wrapping another
// RedirectAuthoritativeDnsServerCache.
if (authoritativeDnsServerCache instanceof RedirectAuthoritativeDnsServerCache) {
return authoritativeDnsServerCache;
}
return new RedirectAuthoritativeDnsServerCache(authoritativeDnsServerCache);
}
private static final class RedirectAuthoritativeDnsServerCache implements AuthoritativeDnsServerCache {
private final AuthoritativeDnsServerCache wrapped;
RedirectAuthoritativeDnsServerCache(AuthoritativeDnsServerCache authoritativeDnsServerCache) {
this.wrapped = authoritativeDnsServerCache;
}
@Override @Override
public DnsServerAddressStream get(String hostname) { public DnsServerAddressStream get(String hostname) {
// To not risk falling into any loop, we will not use the cache while following redirects but only // To not risk falling into any loop, we will not use the cache while following redirects but only
@ -513,19 +534,17 @@ abstract class DnsResolveContext<T> {
@Override @Override
public void cache(String hostname, InetSocketAddress address, long originalTtl, EventLoop loop) { public void cache(String hostname, InetSocketAddress address, long originalTtl, EventLoop loop) {
authoritativeDnsServerCache.cache(hostname, address, originalTtl, loop); wrapped.cache(hostname, address, originalTtl, loop);
} }
@Override @Override
public void clear() { public void clear() {
authoritativeDnsServerCache.clear(); wrapped.clear();
} }
@Override @Override
public boolean clear(String hostname) { public boolean clear(String hostname) {
return authoritativeDnsServerCache.clear(hostname); return wrapped.clear(hostname);
}
}, false).resolve(resolverPromise);
} }
} }