diff options
author | Florian Weimer <fweimer@redhat.com> | 2016-04-27 17:15:57 +0200 |
---|---|---|
committer | Florian Weimer <fweimer@redhat.com> | 2016-05-09 11:35:16 +0200 |
commit | 1e5ac8a1daa360cd9632e5056e4bdf29e18ac2c7 (patch) | |
tree | 978c753da3a8a1fbe649ba08b6ff8af8c395034b | |
parent | 730244f49ad8f46308f5513e58365eed370423cb (diff) | |
download | glibc-1e5ac8a1daa360cd9632e5056e4bdf29e18ac2c7.tar.gz |
nss_dns: Skip over non-PTR records in the netent code [BZ #19868]
This requires additional checks for the RDATA length and the
availability of record metadata.
(cherry picked from commit a12f9431b3808e78b9ed397e4fce7de69410d94d)
-rw-r--r-- | ChangeLog | 7 | ||||
-rw-r--r-- | resolv/nss_dns/dns-network.c | 20 |
2 files changed, 25 insertions, 2 deletions
@@ -1,3 +1,10 @@ +2016-03-25 Florian Weimer <fweimer@redhat.com> + + [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. + 2016-04-27 Florian Weimer <fweimer@redhat.com> [BZ #19831] diff --git a/resolv/nss_dns/dns-network.c b/resolv/nss_dns/dns-network.c index 8f301a706b..ad6acffb8c 100644 --- a/resolv/nss_dns/dns-network.c +++ b/resolv/nss_dns/dns-network.c @@ -345,10 +345,23 @@ getanswer_r (const querybuf *answer, int anslen, struct netent *result, 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 anslen, struct netent *result, 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 anslen, struct netent *result, ++have_answer; } } + else + /* Skip over unknown record data. */ + cp += rdatalen; } if (have_answer) |