Under high load, getaddrinfo() starts sending DNS queries to random
file descriptors, e.g. some unrelated socket connected to a remote service.
The attached code reproduces the bug on at least the following configurations:
Archlinux libc6 2.18
Debian libc6 2.6.11
Debian libc6 2.13-38
Debian libc6 2.17-92
Ubuntu libc6 2.17-0ubuntu5
What the code does is to fill the file descriptor space, closing and creating many file descriptors, to maximize the chances of reproducing the bug:
- a thread listens to a local unix socket
- a thread connects to the unix socket, never writes to it, dups the
connection as much as possible (fills the fd space), closes the dups, and starts
- lots of threads call getaddrinfo()
Under less than a minute, the listener starts reading garbage.
The garbage received by the listener seems to always be a full, well-formed, DNS query. It seems to always be an AAAA query, even when hints.ai_family is AF_INET. All queries are similar, only the id changes.
CVE assigned today at http://seclists.org/oss-sec/2015/q1/316
This issue seems to be confirmed fixed in version 2.20. There was some confusion whether the issue still persists after this version, however that seems to have been limited to a bad testcase. Versions prior to 2.20 are vulnerable to this issue.
The send_dg function in resolv/res_send.c in GNU C Library (aka glibc or
libc6) before 2.20 does not properly reuse file descriptors, which allows
remote attackers to send DNS queries to unintended locations via a large
number of request that trigger a call to the getaddrinfo function.
This issue was resolved and addressed in
GLSA 201602-02 at https://security.gentoo.org/glsa/201602-02
by GLSA coordinator Tobias Heinlein (keytoaster).