glibc 2.21 DNS endless loop in getaddr_r

2014.12.15
Credit: Yash
Risk: Medium
Local: No
Remote: Yes
CVE: N/A
CWE: N/A

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

References:

https://sourceware.org/bugzilla/show_bug.cgi?id=17630
http://seclists.org/oss-sec/2014/q4/1047


Vote for this issue:
50%
50%


 

Thanks for you vote!


 

Thanks for you comment!
Your message is in quarantine 48 hours.

Comment it here.


(*) - required fields.  
{{ x.nick }} | Date: {{ x.ux * 1000 | date:'yyyy-MM-dd' }} {{ x.ux * 1000 | date:'HH:mm' }} CET+1
{{ x.comment }}

Copyright 2024, cxsecurity.com

 

Back to Top