Glibc bug mitigation for getaddrinfo()

Ran across an exploit for glibc today which involves the getaddrinfo() call for DNS resolution. I'm running Ubuntu 12.04 on two Bind9 boxes that face the internet. I'm not sure I totally understand the exploit, but it seems to be caused by a large reply from a malicous DNS server. One of the mitigations is a "firewall that drops UDP DNS packets > 512 bytes" so I've configured netfilter on the DNS servers to drop any UDP > 512 bytes coming from, or going to, port 53: -A INPUT -i lo -j ACCEPT -A INPUT -p udp --sport 53 -m length --length 511:65535 -j DROP -A INPUT -p udp --dport 53 -m length --length 511:65535 -j DROP -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT

Is there a better way to do this with a Bind setting or anything? I've tested the rule with scapy and it does indeed block a UDP packet > 512 tossed at port 53.

UPDATED per responses: -A INPUT -i lo -j ACCEPT -A INPUT -p udp --sport 53 -m length --length 949:65535 -j DROP -A INPUT -p udp --dport 53 -m length --length 949:65535 -j DROP -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT

and /etc/bind/named.conf.options

options {
   ...
   // 2016-02-17 - tmb - glibc exploit mitigation
   edns-udp-size 900 ;
   max-udp-size 900 ;
};

UPDATE 2: As pointed out by atdre below, Cloudflare tried the above technique and although the entire payload could not be transferred, memory corruption was still a possibility. I think I'll look into Unbound.


If you are running bind locally, this gives you a test:

dig @127.0.0.1 tcf.rs.dns-oarc.net txt

as described here: https://www.dns-oarc.net/oarc/services/replysizetest .

You will get a reply like this:

root@myhost:~# dig @127.0.0.1 tcf.rs.dns-oarc.net txt

; <<>> DiG <<>> @127.0.0.1 tcf.rs.dns-oarc.net txt
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 61575
;; flags: qr rd ra; QUERY: 1, ANSWER: 5, AUTHORITY: 26, ADDITIONAL: 27

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1024
;; QUESTION SECTION:
;tcf.rs.dns-oarc.net.           IN      TXT

;; ANSWER SECTION:
tcf.rs.dns-oarc.net.    60      IN      CNAME   tcf.x981.rs.dns-oarc.net.
tcf.x981.rs.dns-oarc.net. 59    IN      CNAME   tcf.x986.x981.rs.dns-oarc.net.
tcf.x986.x981.rs.dns-oarc.net. 58 IN    CNAME   tcf.x991.x986.x981.rs.dns-oarc.net.
tcf.x991.x986.x981.rs.dns-oarc.net. 57 IN TXT   "Tested at 2016-02-17 15:44:36 UTC"
tcf.x991.x986.x981.rs.dns-oarc.net. 57 IN TXT   "xx.xx.xx.xx DNS reply size limit is at least 991"

and you can add the bind option

options {
  ...
  edns-udp-size 1024 ;
  max-udp-size 1024 ;
};

in the file named.conf

as described here: https://labs.ripe.net/Members/anandb/content-testing-your-resolver-dns-reply-size-issues .

I would use this in conjunction with other mitigations too.


While A firewall that drops UDP DNS packets > 512 bytes. mitigates the exploit (over UDP specifically, TCP can still be an attack vector) it's also not correct behaviour and breaks other functionality instead.

Since the introduction of EDNS0 there is no such limit in the DNS spec and you will cause breakages for valid traffic by just dropping packets.

What birdwes suggests, with configuring a resolver nameserver to limit response sizes back to its clients is a better way as clients will at least be properly notified (truncated response) as per the specs instead of just silence and eventually a timeout, but the proper solution is to install patched glibc (that's where something is wrong, the size is not wrong).