I have a service where domain names to be resolved come from untrusted sources. Recently, it kept crashing from running out of memory. I narrowed down the possible reasons, and came to the conclusion that it must be related to the recent flux of DNS requests. However, the service doesn't store anything after resolving domain names, so this seemed unlikely, but I tried spamming my service with requests that result in it resolving domain names, just in case. It did die from that. I then narrowed down the code to this after concluding that there is no memory being stored on my code's behalf:
import java.math.*;
import java.net.*;
class A {
static {
try {
for (BigInteger i = BigInteger.ZERO; i==i; i = i.add(BigInteger.ONE))
Inet4Address.getByName("a"+i+".dog");
} catch (Exception e) {throw new RuntimeException(e);}
}
}
I setup dnsmasq with this line in /etc/dnsmasq.conf
to make the resolutions faster:
address=/dog/127.0.0.1
At first when I ran this, it survived for days, so it seemed this was not the problem. But then I ran it with my script that I use to start my service, which enables the security manager, and it crashes:
$ javac A.java && java -Xmx80m -Djava.security.manager A
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
Could not find the main class: A. Program will exit.
The security manager makes my program vulnerable to this denial of service attack. Why? How to fix it?
$ java -version
java version "1.6.0_27"
OpenJDK Runtime Environment (IcedTea6 1.12.6) (Gentoo build 1.6.0_27-b27)
OpenJDK 64-Bit Server VM (build 20.0-b12, mixed mode)