2016-03-25 Florian Weimer [BZ #19868] * resolv/nss_dns/dns-network.c (getanswer_r): Implement additional DNS packet syntax checks (which were not needed before). Skip over non-PTR records. Index: glibc-2.23/resolv/nss_dns/dns-network.c =================================================================== --- glibc-2.23.orig/resolv/nss_dns/dns-network.c +++ glibc-2.23/resolv/nss_dns/dns-network.c @@ -345,10 +345,23 @@ getanswer_r (const querybuf *answer, int if (n < 0 || res_dnok (bp) == 0) break; cp += n; + + if (end_of_message - cp < 10) + { + __set_h_errno (NO_RECOVERY); + return NSS_STATUS_UNAVAIL; + } + GETSHORT (type, cp); GETSHORT (class, cp); cp += INT32SZ; /* TTL */ - GETSHORT (n, cp); + uint16_t rdatalen; + GETSHORT (rdatalen, cp); + if (end_of_message - cp < rdatalen) + { + __set_h_errno (NO_RECOVERY); + return NSS_STATUS_UNAVAIL; + } if (class == C_IN && type == T_PTR) { @@ -370,7 +383,7 @@ getanswer_r (const querybuf *answer, int cp += n; return NSS_STATUS_UNAVAIL; } - cp += n; + cp += rdatalen; if (alias_pointer + 2 < &net_data->aliases[MAX_NR_ALIASES]) { *alias_pointer++ = bp; @@ -381,6 +394,9 @@ getanswer_r (const querybuf *answer, int ++have_answer; } } + else + /* Skip over unknown record data. */ + cp += rdatalen; } if (have_answer)