Fix potential infinite loop when resolving CNAME records
Related: #4771 Motivation: A malicious or misconfigured DNS server can send the CNAME records that resolve into each other, causing an unexpected infinite loop in DnsNameResolverContext.onResponseCNAME(). Modifications: - Remove the dereferenced CNAME from the alias map so that infinite loop is impossible. - Fix inspection warnings and typos in DnsNameResolverTest Result: Fixes #4771
This commit is contained in:
parent
e2d4e22243
commit
ef8dcae9af
@ -283,8 +283,10 @@ abstract class DnsNameResolverContext<T> {
|
|||||||
final String name = question.name().toLowerCase(Locale.US);
|
final String name = question.name().toLowerCase(Locale.US);
|
||||||
String resolved = name;
|
String resolved = name;
|
||||||
boolean found = false;
|
boolean found = false;
|
||||||
for (;;) {
|
while (!cnames.isEmpty()) { // Do not attempt to call Map.remove() when the Map is empty
|
||||||
String next = cnames.get(resolved);
|
// because it can be Collections.emptyMap()
|
||||||
|
// whose remove() throws a UnsupportedOperationException.
|
||||||
|
final String next = cnames.remove(resolved);
|
||||||
if (next != null) {
|
if (next != null) {
|
||||||
found = true;
|
found = true;
|
||||||
resolved = next;
|
resolved = next;
|
||||||
|
@ -265,7 +265,7 @@ public class DnsNameResolverTest {
|
|||||||
private static final TestDnsServer dnsServer = new TestDnsServer();
|
private static final TestDnsServer dnsServer = new TestDnsServer();
|
||||||
private static final EventLoopGroup group = new NioEventLoopGroup(1);
|
private static final EventLoopGroup group = new NioEventLoopGroup(1);
|
||||||
|
|
||||||
private DnsNameResolverBuilder newResolver() {
|
private static DnsNameResolverBuilder newResolver() {
|
||||||
return new DnsNameResolverBuilder(group.next())
|
return new DnsNameResolverBuilder(group.next())
|
||||||
.channelType(NioDatagramChannel.class)
|
.channelType(NioDatagramChannel.class)
|
||||||
.nameServerAddresses(DnsServerAddresses.singleton(dnsServer.localAddress()))
|
.nameServerAddresses(DnsServerAddresses.singleton(dnsServer.localAddress()))
|
||||||
@ -273,7 +273,7 @@ public class DnsNameResolverTest {
|
|||||||
.optResourceEnabled(false);
|
.optResourceEnabled(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
private DnsNameResolverBuilder newResolver(InternetProtocolFamily... resolvedAddressTypes) {
|
private static DnsNameResolverBuilder newResolver(InternetProtocolFamily... resolvedAddressTypes) {
|
||||||
return newResolver()
|
return newResolver()
|
||||||
.resolvedAddressTypes(resolvedAddressTypes);
|
.resolvedAddressTypes(resolvedAddressTypes);
|
||||||
}
|
}
|
||||||
@ -349,7 +349,7 @@ public class DnsNameResolverTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Map<String, InetAddress> testResolve0(DnsNameResolver resolver, Set<String> excludedDomains)
|
private static Map<String, InetAddress> testResolve0(DnsNameResolver resolver, Set<String> excludedDomains)
|
||||||
throws InterruptedException {
|
throws InterruptedException {
|
||||||
|
|
||||||
assertThat(resolver.isRecursionDesired(), is(true));
|
assertThat(resolver.isRecursionDesired(), is(true));
|
||||||
@ -482,7 +482,7 @@ public class DnsNameResolverTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private UnknownHostException resolveNonExistentDomain(DnsNameResolver resolver) {
|
private static UnknownHostException resolveNonExistentDomain(DnsNameResolver resolver) {
|
||||||
try {
|
try {
|
||||||
resolver.resolve("non-existent.netty.io").sync();
|
resolver.resolve("non-existent.netty.io").sync();
|
||||||
fail();
|
fail();
|
||||||
@ -505,8 +505,7 @@ public class DnsNameResolverTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void resolve(DnsNameResolver resolver, Map<String, Future<InetAddress>> futures, String hostname) {
|
private static void resolve(DnsNameResolver resolver, Map<String, Future<InetAddress>> futures, String hostname) {
|
||||||
|
|
||||||
futures.put(hostname, resolver.resolve(hostname));
|
futures.put(hostname, resolver.resolve(hostname));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -580,7 +579,7 @@ public class DnsNameResolverTest {
|
|||||||
// This is a hack to allow to also test for AAAA resolution as DnsMessageEncoder
|
// This is a hack to allow to also test for AAAA resolution as DnsMessageEncoder
|
||||||
// does not support it and it is hard to extend, because the interesting methods
|
// does not support it and it is hard to extend, because the interesting methods
|
||||||
// are private...
|
// are private...
|
||||||
// In case of RecordType.AAAA we need to encode the RecordType by ourself.
|
// In case of RecordType.AAAA we need to encode the RecordType by ourselves.
|
||||||
if (record.getRecordType() == RecordType.AAAA) {
|
if (record.getRecordType() == RecordType.AAAA) {
|
||||||
try {
|
try {
|
||||||
recordEncoder.put(buf, record);
|
recordEncoder.put(buf, record);
|
||||||
@ -639,10 +638,10 @@ public class DnsNameResolverTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static String nextIp() {
|
private static String nextIp() {
|
||||||
return ippart() + "." + ippart() + '.' + ippart() + '.' + ippart();
|
return ipPart() + "." + ipPart() + '.' + ipPart() + '.' + ipPart();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int ippart() {
|
private static int ipPart() {
|
||||||
return NUMBERS[index(NUMBERS.length)];
|
return NUMBERS[index(NUMBERS.length)];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -672,10 +671,10 @@ public class DnsNameResolverTest {
|
|||||||
} while (ThreadLocalRandom.current().nextBoolean());
|
} while (ThreadLocalRandom.current().nextBoolean());
|
||||||
break;
|
break;
|
||||||
case MX:
|
case MX:
|
||||||
int prioritity = 0;
|
int priority = 0;
|
||||||
do {
|
do {
|
||||||
rm.put(DnsAttribute.DOMAIN_NAME, nextDomain());
|
rm.put(DnsAttribute.DOMAIN_NAME, nextDomain());
|
||||||
rm.put(DnsAttribute.MX_PREFERENCE, String.valueOf(++prioritity));
|
rm.put(DnsAttribute.MX_PREFERENCE, String.valueOf(++priority));
|
||||||
} while (ThreadLocalRandom.current().nextBoolean());
|
} while (ThreadLocalRandom.current().nextBoolean());
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
Loading…
Reference in New Issue
Block a user