Bug 1347549 (CVE-2016-10739)

Summary: CVE-2016-10739 glibc: getaddrinfo should reject IP addresses with trailing characters
Product: [Other] Security Response Reporter: Cedric Buissart <cbuissar>
Component: vulnerabilityAssignee: Red Hat Product Security <security-response-team>
Status: CLOSED ERRATA QA Contact:
Severity: medium Docs Contact:
Priority: medium    
Version: unspecifiedCC: arjun.is, ashankar, codonell, dj, fweimer, glibc-bugzilla, jakub, law, mfabian, mnewsome, pfrankli, sardella, siddhesh, vstinner
Target Milestone: ---Keywords: Reopened, Security
Target Release: ---   
Hardware: All   
OS: Linux   
Whiteboard:
Fixed In Version: glibc 2.29 Doc Type: If docs needed, set a value
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2019-08-06 13:18:22 UTC Type: ---
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:
Bug Depends On: 1331390, 1673465, 1727241    
Bug Blocks: 1303701    

Description Cedric Buissart 2016-06-17 08:33:19 UTC
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 :
https://sourceware.org/bugzilla/show_bug.cgi?id=20018

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:
http://blog.blindspotsecurity.com/2016/06/advisory-http-header-injection-in.html

Comment 1 Cedric Buissart 2016-06-17 08:44:17 UTC
Created attachment 1168979 [details]
Demo program

Comment 2 Cedric Buissart 2016-06-17 09:26:07 UTC
[ 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".

Comment 3 Cedric Buissart 2016-06-17 09:27:05 UTC
[ 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.

Comment 5 Andrej Nemec 2017-09-08 12:09:11 UTC
Statement:

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/.

Comment 10 Victor Stinner 2019-07-05 10:17:44 UTC
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).

Comment 11 Tomas Hoger 2019-07-09 14:17:36 UTC
Upstream commit:

https://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=108bc4049f8ae82710aec26a92ffdb4b439c83fd

Included in upstream glibc version 2.29, released in Feb 2019:

https://sourceware.org/ml/libc-announce/2019/msg00000.html

Comment 12 errata-xmlrpc 2019-08-06 12:16:23 UTC
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

Comment 13 Product Security DevOps Team 2019-08-06 13:18:22 UTC
This bug is now closed. Further updates for individual products will be reflected on the CVE page(s):

https://access.redhat.com/security/cve/cve-2016-10739

Comment 14 errata-xmlrpc 2019-11-05 21:04:00 UTC
This issue has been addressed in the following products:

  Red Hat Enterprise Linux 8

Via RHSA-2019:3513 https://access.redhat.com/errata/RHSA-2019:3513