public inbox for glibc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug network/17630] New: endless loop in getaddr_r
@ 2014-11-20 13:44 yashavanth.hsn at gmail dot com
  2014-11-20 14:47 ` [Bug network/17630] " schwab@linux-m68k.org
                   ` (25 more replies)
  0 siblings, 26 replies; 27+ messages in thread
From: yashavanth.hsn at gmail dot com @ 2014-11-20 13:44 UTC (permalink / raw)
  To: glibc-bugs

https://sourceware.org/bugzilla/show_bug.cgi?id=17630

            Bug ID: 17630
           Summary: endless loop in getaddr_r
           Product: glibc
           Version: 2.11
            Status: NEW
          Severity: normal
          Priority: P2
         Component: network
          Assignee: unassigned at sourceware dot org
          Reporter: yashavanth.hsn at gmail dot com

Hallo,

DESCRIPTION: getanswer_r ends in infinite loop on certain inputs.
GLIBC_VERSION: 2.11.3

Note: I am novice into glibc and don't have complete understanding of glibc
with respect to dns resolution. 

IN DETAIL: 
When I execute iptables-restore on one of our Lab's system, iptables-restore
started consuming 100% cpu all the time. I did strace on iptables-restore I
found that most of the cpu is comsumed by NSS DNS resolver of libc as given
below.

 67.50%  iptables-restor  libnss_dns-2.11.3.so  [.] getanswer_r
 15.12%  iptables-restor  libc-2.11.3.so        [.] __strcasecmp
  9.02%  iptables-restor  libc-2.11.3.so        [.] __ctype_b_loc
  7.02%  iptables-restor  libc-2.11.3.so        [.] __i686.get_pc_thunk.bx
  0.77%  iptables-restor  libnss_dns-2.11.3.so  [.] 0x00000c00
  0.18%  iptables-restor  [kernel.kallsyms]     [k] read_hpet  

To get more details, I attached iptables-restore to gdb with debugging symbols
loaded and found that glibc takes most of the CPU, since it ends in endless
loop. when, 

1. have_answer is set 
2. net_i is set to BYNAME
3. result->n_aliases is set to ns5.dsredirections.com ( i,e in the code ap is
set to ns5.dsredirections.com )

With this input, I found that the loop never exists and continue to process the
same input again and again. 

Basically as per the code comment, the loop functionality is to :

               /* Check each alias name for being of the forms:
                   4.3.2.1.in-addr.arpa         = net 1.2.3.4
                   3.2.1.in-addr.arpa           = net 0.1.2.3
                   2.1.in-addr.arpa             = net 0.0.1.2
                   1.in-addr.arpa               = net 0.0.0.1
                */

But then the question is : 
1. Is this is a valid input or not to getanswer_r.

on the other hand, when the input is of bad form like ns5.dsredirections.com,
code has to detect and come out of loop.

FINDINGS and SOLUTION: 

I found that the most recent Upstream code does not have this fixed as this
part of the code is stable since 2002.

** I tried to patch glibc as given below. ( Not sure if its correct and does
not break other scenarios )

    avoid infinite loop for invalid entry.

    getaddr_r gets into infinite loop for invalid entries
    like ns5.dsredirections.com then it never detects and
    breaks from  infinite loop.

    This patch detects the entries with non digit and
    non hexadecimal digits and returns.

diff --git a/glibc/glibc-2.11.3-getaddr.diff b/glibc/glibc-2.11.3-getaddr.diff
new file mode 100644
index 0000000..664b033
--- /dev/null
+++ b/glibc/glibc-2.11.3-getaddr.diff
@@ -0,0 +1,42 @@
+Index: glibc-2.11.3/resolv/nss_dns/dns-network.c
+===================================================================
+--- glibc-2.11.3.orig/resolv/nss_dns/dns-network.c
++++ glibc-2.11.3/resolv/nss_dns/dns-network.c
+@@ -414,6 +414,7 @@ getanswer_r (const querybuf *answer, int
+               uint32_t val = 0;       /* Accumulator for n_net value.  */
+               unsigned int shift = 0; /* Which part we are parsing now.  */
+               const char *p = *ap; /* Consuming the string.  */
++              unsigned int invalid = 0;
+               do
+                 {
+                   /* Match the leading 0 or 0[xX] base indicator.  */
+@@ -440,12 +441,23 @@ getanswer_r (const querybuf *answer, int
+                         part = (part * base) + (*p - '0');
+                       else if (base == 16 && isxdigit (*p))
+                         part = (part << 4) + 10 + (tolower (*p) - 'a');
++      
++                      /* when neither digit nor hexadigit, then its a invalid
*/    
++                      if ( !isdigit(*p) && !isxdigit(*p) && *p != '.')
++                        {
++                             invalid = 1;
++                      }
++  
+                       ++p;
+                     } while (*p != '\0' && *p != '.');
+ 
++                  if( invalid )
++                      return NSS_STATUS_NOTFOUND;
++              
+                   if (*p != '.')
+                     break;    /* Bad form.  Give up on this name.  */
+ 
++                      
+                   /* Install this as the next more significant byte.  */
+                   val |= part << shift;
+                   shift += 8;
+@@ -470,4 +482,4 @@ getanswer_r (const querybuf *answer, int
+ 
+   __set_h_errno (TRY_AGAIN);
+   return NSS_STATUS_TRYAGAIN;
+-}
++}  

After the patched glibc is installed, iptables-restore does not run infinitely
and everything is normal.

Could you please let me know, whether this will be fixed moving further. 

I would like to extend my help with any information if needed.

Best,
Yash

-- 
You are receiving this mail because:
You are on the CC list for the bug.


^ permalink raw reply	[flat|nested] 27+ messages in thread

end of thread, other threads:[~2015-02-23 15:02 UTC | newest]

Thread overview: 27+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-11-20 13:44 [Bug network/17630] New: endless loop in getaddr_r yashavanth.hsn at gmail dot com
2014-11-20 14:47 ` [Bug network/17630] " schwab@linux-m68k.org
2014-11-24 16:29 ` yashavanth.hsn at gmail dot com
2014-11-24 16:31 ` yashavanth.hsn at gmail dot com
2014-11-24 16:58 ` schwab@linux-m68k.org
2014-11-25  9:48 ` yashavanth.hsn at gmail dot com
2014-12-09 13:34 ` schwab@linux-m68k.org
2014-12-12 14:06 ` fweimer at redhat dot com
2014-12-15  9:26 ` yashavanth.hsn at gmail dot com
2014-12-15  9:34 ` schwab@linux-m68k.org
2014-12-15  9:50 ` yashavanth.hsn at gmail dot com
2014-12-15  9:50 ` fweimer at redhat dot com
2014-12-16  9:10 ` cvs-commit at gcc dot gnu.org
2014-12-16  9:11 ` fweimer at redhat dot com
2014-12-18  1:07 ` cvs-commit at gcc dot gnu.org
2014-12-18  6:17 ` [Bug network/17630] endless loop in getaddr_r (CVE-2014-9402) fweimer at redhat dot com
2015-01-14 12:19 ` cvs-commit at gcc dot gnu.org
2015-01-14 13:13 ` cvs-commit at gcc dot gnu.org
2015-01-16 16:59 ` cvs-commit at gcc dot gnu.org
2015-01-16 17:02 ` cvs-commit at gcc dot gnu.org
2015-01-16 17:03 ` cvs-commit at gcc dot gnu.org
2015-01-21 13:56 ` cvs-commit at gcc dot gnu.org
2015-01-29 18:50 ` cvs-commit at gcc dot gnu.org
2015-02-12 13:05 ` cvs-commit at gcc dot gnu.org
2015-02-23 14:06 ` cvs-commit at gcc dot gnu.org
2015-02-23 14:23 ` cvs-commit at gcc dot gnu.org
2015-02-23 15:02 ` cvs-commit at gcc dot gnu.org

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).