Bug 981942

Summary: CVE-2013-7424 glibc: ping6 with idn causes crash
Product: Red Hat Enterprise Linux 6 Reporter: Chris Hills <chaz>
Component: glibcAssignee: Siddhesh Poyarekar <spoyarek>
Status: CLOSED ERRATA QA Contact: Arjun Shankar <ashankar>
Severity: medium Docs Contact:
Priority: unspecified    
Version: 6.4CC: ashankar, fweimer, mfranc, mnewsome, pfrankli, spoyarek
Target Milestone: rcKeywords: Security
Target Release: ---   
Hardware: All   
OS: Linux   
Whiteboard:
Fixed In Version: glibc-2.12-1.135.el6 Doc Type: Bug Fix
Doc Text:
Name lookup of internationalized domain names using getaddrinfo could result in the calling program crashing with an abort. This update fixes the getaddrinfo code to resolve the crash.
Story Points: ---
Clone Of: Environment:
Last Closed: 2014-10-14 04:41:48 UTC Type: Bug
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:    
Bug Blocks: 1186614    
Attachments:
Description Flags
full backtrace during the crash none

Description Chris Hills 2013-07-07 08:04:57 UTC
Description of problem:
When supplying an internationalized domain name to ping6 it causes a crash in ping6.

Version-Release number of selected component (if applicable):
iputils-20071127-17.el6_4.x86_64

How reproducible:
Every time, on both x86_64 and x86.

Steps to Reproduce:
1. Open a terminal.
2. Enter the command `ping6 தளம்.பாராளுமன்றம்.இலங்கை.`

Actual results:
ping6 crashes

Expected results:
ping6 does not crash.

Additional info:
# ping6 தளம்.பாராளுமன்றம்.இலங்கை.
*** glibc detected *** ping6: munmap_chunk(): invalid pointer: 0xbfb787a6 ***
======= Backtrace: =========
/lib/libc.so.6(+0x390e31)[0xde7e31]
/lib/libc.so.6(+0x3e6c86)[0xe3dc86]
/lib/libc.so.6(getaddrinfo+0x15b)[0xe403db]
ping6(main+0x5da)[0xbb8aba]
/lib/libc.so.6(__libc_start_main+0xe6)[0xd8dce6]
ping6(+0x1551)[0xbb7551]
======= Memory map: ========
001fa000-00217000 r-xp 00000000 fd:01 16845      /lib/libgcc_s-4.4.7-20120601.so.1
00217000-00218000 rw-p 0001d000 fd:01 16845      /lib/libgcc_s-4.4.7-20120601.so.1
002c8000-002dd000 r-xp 00000000 fd:01 19806      /lib/libresolv-2.12.so
002dd000-002de000 ---p 00015000 fd:01 19806      /lib/libresolv-2.12.so
002de000-002df000 r--p 00015000 fd:01 19806      /lib/libresolv-2.12.so
002df000-002e0000 rw-p 00016000 fd:01 19806      /lib/libresolv-2.12.so
002e0000-002e2000 rw-p 00000000 00:00 0
00676000-00694000 r-xp 00000000 fd:01 30540      /lib/ld-2.12.so
00694000-00695000 r--p 0001d000 fd:01 30540      /lib/ld-2.12.so
00695000-00696000 rw-p 0001e000 fd:01 30540      /lib/ld-2.12.so
006d1000-006d6000 r-xp 00000000 fd:01 8399       /lib/libnss_dns-2.12.so
006d6000-006d7000 r--p 00004000 fd:01 8399       /lib/libnss_dns-2.12.so
006d7000-006d8000 rw-p 00005000 fd:01 8399       /lib/libnss_dns-2.12.so
007a9000-007d6000 r-xp 00000000 fd:01 8387       /lib/libcidn-2.12.so
007d6000-007d7000 r--p 0002c000 fd:01 8387       /lib/libcidn-2.12.so
007d7000-007d8000 rw-p 0002d000 fd:01 8387       /lib/libcidn-2.12.so
00bb6000-00bbe000 r-xp 00000000 fd:01 18000      /bin/ping6
00bbe000-00bbf000 rw-p 00007000 fd:01 18000      /bin/ping6
00bbf000-00be1000 rw-p 00000000 00:00 0
00caa000-00cb6000 r-xp 00000000 fd:01 8401       /lib/libnss_files-2.12.so
00cb6000-00cb7000 r--p 0000b000 fd:01 8401       /lib/libnss_files-2.12.so
00cb7000-00cb8000 rw-p 0000c000 fd:01 8401       /lib/libnss_files-2.12.so
00d77000-00f07000 r-xp 00000000 fd:01 30541      /lib/libc-2.12.so
00f07000-00f08000 ---p 00190000 fd:01 30541      /lib/libc-2.12.so
00f08000-00f0a000 r--p 00190000 fd:01 30541      /lib/libc-2.12.so
00f0a000-00f0b000 rw-p 00192000 fd:01 30541      /lib/libc-2.12.so
00f0b000-00f0e000 rw-p 00000000 00:00 0
00fcf000-00fd0000 r-xp 00000000 00:00 0          [vdso]
02860000-02881000 rw-p 00000000 00:00 0          [heap]
b75b2000-b77b2000 r--p 00000000 fd:01 8359       /usr/lib/locale/locale-archive
b77b2000-b77b3000 rw-p 00000000 00:00 0
b77b8000-b77ba000 rw-p 00000000 00:00 0
bfb64000-bfb79000 rw-p 00000000 00:00 0          [stack]
Aborted (core dumped)

Comment 2 Jan Synacek 2013-07-08 12:45:10 UTC
Created attachment 770465 [details]
full backtrace during the crash

The respective code from ping6.c:

struct addrinfo hints, *ai;
int gai;
...
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_INET6;
hints.ai_flags = AI_IDN;
gai = getaddrinfo(target, NULL, &hints, &ai); // <--- crash here
if (gai) {
	fprintf(stderr, "unknown host\n");
	exit(2);
}

Comment 3 Jan Synacek 2013-07-08 12:48:40 UTC
Switching to glibc.

Comment 4 Carlos O'Donell 2013-07-08 13:54:18 UTC
(gdb) bt
#0  0x00007ff8cc255895 in raise (sig=6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:64
#1  0x00007ff8cc257075 in abort () at abort.c:92
#2  0x00007ff8cc2937a7 in __libc_message (do_abort=2, fmt=0x7ff8cc37af80 "*** glibc detected *** %s: %s: 0x%s ***\n")
    at ../sysdeps/unix/sysv/linux/libc_fatal.c:198
#3  0x00007ff8cc2990d6 in malloc_printerr (action=3, str=0x7ff8cc37afb0 "munmap_chunk(): invalid pointer", 
    ptr=<value optimized out>) at malloc.c:6311
#4  0x00007ff8cc2f3252 in gaih_inet (
    name=0x7fff88db2536 "தளம்.பாராளுமன்றம்.இலங்கை.", 
    service=<value optimized out>, req=<value optimized out>, pai=<value optimized out>, naddrs=0x7fff88db1d48)
    at ../sysdeps/posix/getaddrinfo.c:1250
#5  0x00007ff8cc2f5da0 in getaddrinfo (
    name=0x7fff88db2536 "தளம்.பாராளுமன்றம்.இலங்கை.", 
    service=<value optimized out>, hints=0x7fff88db1dc0, pai=0x7fff88db1e18) at ../sysdeps/posix/getaddrinfo.c:2361
#6  0x00007ff8cc7db2f5 in main ()


The problem is like this:

* In gaih_inet we pass this IDN to __idna_to_ascii_lz to get back a canonicalized name we can use.
* If the output string of __idna_to_ascii_lz (second argument) has a different pointer value from the IDN then we assume a string has been allocated that we need to free.
* Later we free name (the static string).

The disconnect is that we did not assign `name' to the new value `p' which needs to be freed.

The upstream code is this:
~~~
          /* In case the output string is the same as the input string
             no new string has been allocated.  */
          if (p != name)
            {
              name = p;
              malloc_name = true;
            }
~~~

The rhel-6.5 code is this:
~~~
 432           /* In case the output string is the same as the input string
 433              no new string has been allocated.  */
 434           if (p != name)
 435             malloc_name = true;
~~~

The upstream fix is this:

commit 2e96f1c73b06e81da59ef7fffa426dc201875f31
Author: Andreas Schwab <schwab>
Date:   Thu Aug 4 15:42:10 2011 -0400

    Fix encoding name for IDN in getaddrinfo

~~~
diff --git a/ChangeLog b/ChangeLog
index fbacbd5..0392853 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2011-07-26  Andreas Schwab  <schwab>
+
+       * sysdeps/posix/getaddrinfo.c (gaih_inet): Don't discard result of
+       encoding to ACE if AI_IDN.
+
 2011-08-01  Jakub Jelinek  <jakub>
 
        * sysdeps/ieee754/dbl-64/k_rem_pio2.c (__kernel_rem_pio2): Fix up fq
diff --git a/sysdeps/posix/getaddrinfo.c b/sysdeps/posix/getaddrinfo.c
index 6d574c5..a5aafe9 100644
--- a/sysdeps/posix/getaddrinfo.c
+++ b/sysdeps/posix/getaddrinfo.c
@@ -432,7 +432,10 @@ gaih_inet (const char *name, const struct gaih_service *service,
          /* In case the output string is the same as the input string
             no new string has been allocated.  */
          if (p != name)
-           malloc_name = true;
+           {
+             name = p;
+             malloc_name = true;
+           }
        }
 #endif
~~~

According to http://sourceware.org/glibc/wiki/Glibc%20Timeline, that fixed happened in the 2.15 development cycle which would not have been in rhel-6.5 which uses 2.12.

This fix needs backporting to correct this issue.

Moving to rhel-6.6.

Comment 7 errata-xmlrpc 2014-10-14 04:41:48 UTC
Since the problem described in this bug report should be
resolved in a recent advisory, it has been closed with a
resolution of ERRATA.

For information on the advisory, and where to find the updated
files, follow the link below.

If the solution does not work for you, open a new bug report.

http://rhn.redhat.com/errata/RHSA-2014-1391.html