X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Fresolve%2Fresolved-dns-packet.c;h=a9bd8b13988dc31d6e5641921097be38fc3d6e08;hb=56f64d95763a799ba4475daf44d8e9f72a1bd474;hp=e5d07b3b1ff06666e4be428fd4f78ac31ec62b48;hpb=725ca0e53a5a1e4093c494623253a2f312c02bc0;p=elogind.git diff --git a/src/resolve/resolved-dns-packet.c b/src/resolve/resolved-dns-packet.c index e5d07b3b1..a9bd8b139 100644 --- a/src/resolve/resolved-dns-packet.c +++ b/src/resolve/resolved-dns-packet.c @@ -860,7 +860,7 @@ fail: int dns_packet_read_name(DnsPacket *p, char **_ret, bool allow_compression, size_t *start) { - size_t saved_rindex, after_rindex = 0; + size_t saved_rindex, after_rindex = 0, jump_barrier; _cleanup_free_ char *ret = NULL; size_t n = 0, allocated = 0; bool first = true; @@ -870,6 +870,7 @@ int dns_packet_read_name(DnsPacket *p, char **_ret, assert(_ret); saved_rindex = p->rindex; + jump_barrier = p->rindex; for (;;) { uint8_t c, d; @@ -916,7 +917,7 @@ int dns_packet_read_name(DnsPacket *p, char **_ret, goto fail; ptr = (uint16_t) (c & ~0xc0) << 8 | (uint16_t) d; - if (ptr < DNS_PACKET_HEADER_SIZE || ptr >= saved_rindex) { + if (ptr < DNS_PACKET_HEADER_SIZE || ptr >= jump_barrier) { r = -EBADMSG; goto fail; } @@ -924,9 +925,13 @@ int dns_packet_read_name(DnsPacket *p, char **_ret, if (after_rindex == 0) after_rindex = p->rindex; + /* Jumps are limited to a "prior occurence" (RFC-1035 4.1.4) */ + jump_barrier = ptr; p->rindex = ptr; - } else + } else { + r = -EBADMSG; goto fail; + } } if (!GREEDY_REALLOC(ret, allocated, n + 1)) { @@ -1109,6 +1114,13 @@ int dns_packet_read_rr(DnsPacket *p, DnsResourceRecord **ret, size_t *start) { case DNS_TYPE_TXT: { char *s; + /* RFC 1035 says that TXT must be at least one + string. Reject empty records. */ + if (!rdlength) { + r = -EBADMSG; + goto fail; + } + while (p->rindex < offset + rdlength) { r = dns_packet_read_string(p, &s, NULL); if (r < 0)