For historic reasons, inet_addr and inet_aton accept trailing garbage. Some parsers rely on this (for example, libresolv when it parses “nameserver” directives in /etc/resolv.conf).
This causes problems because some applications assume that a successful parse as an IPv4 address means that the string consists of just an IPv4 address, and nothing more.
Glibc should add a check for trailing garbage and relegate the old behavior to a compatibility symbol.
For backporting, glibc should just fix getaddrinfo (and related functions if necessary) so that they will not accept trailing garbage.
Upstream bug :
Additional note :
When used in combination with flaw described in CVE-2016-5699, an attacker could direct an HTTP connection to a malicious server, using the following combined issues:
* Python's httplib does not validate HTTP header values. A malicious 'Host' header with quoted new lines can inject additional headers and more
* glibc's getaddrinfo() ignores new lines and everything after a new line character when the first part looks like a IPv4 address
See the following blog post for additional information:
Created attachment 1168979 [details]
[ Copy of Christian Heimes' original comment from BZ 1303699 ]
compile and run with gcc -o hostname hostname.c && ./hostname
The demo uses gethostbyname() and getaddrinfo() with AF_INET hint to look up the hostname "127.0.0.1\r\nspam".
[ Copy of Carlos O'Donell's original comment from BZ 1303699 ]
The glibc function inet_aton accepts input as valid if said input is a IPv4 address followed by zero or more characters that are valid space as decided by isspace, with the rest of the string after the first space being ignored. As '\r' is a valid space character the rest of the string is ignored (includeing the '\r').
This flexible behaviour is allowed because it makes parsing space-separated lists of addresses (as C strings) easier to manage. You advance the pointer between the address blocks and call inet_aton. In this case getaddrinfo uses inet_aton to determine the validity of the input string, and so considers "127.0.0.1\r\nspam" a valid name parameter and it is immediately converted into the address structure for 127.0.0.1.
The flexible behaviour is used internally in several places in glibc to parse configuration files.
I'd suggest glibc should fix it like this, but upstream needs consulting:
- Version inet_aton to allow the old behaviour and keep it for old programs.
- The new version should strictly reject any IPv4 address with garbage.
- Code that relies on the old behaviour needs to be updated to strdupa and then split the string and parse the pieces.
This isn't going to get fixed any time soon, so the python fix certainly has to go in.
Red Hat Product Security has rated this issue as having Moderate security impact. This issue is not currently planned to be addressed in future updates. For additional information, refer to the Issue Severity Classification: https://access.redhat.com/security/updates/classification/.
FYI a similar issue has been reported to Python: https://bugs.python.org/issue37495
Python socket.inet_aton() is a thin wrapper to the C function inet_aton() (so to glibc inet_aton() in Fedora and RHEL).
Included in upstream glibc version 2.29, released in Feb 2019:
This issue has been addressed in the following products:
Red Hat Enterprise Linux 7
Via RHSA-2019:2118 https://access.redhat.com/errata/RHSA-2019:2118
This bug is now closed. Further updates for individual products will be reflected on the CVE page(s):