From f1d178cce1ada81346fb864c8f95aa2163b37a56 Mon Sep 17 00:00:00 2001 From: Tom Gundersen Date: Thu, 23 Jul 2015 12:57:58 +0200 Subject: resolved: packet - fail on invalid zero-length data Most blobs (keys, signatures, ...) should have a specific size given by the relevant algorithm. However, as we don't use/verify the algorithms yet, let's just ensure that we don't read out zero-length data in cases where this does not make sense. The only exceptions, where zero-length data is allowed are in the NSEC3 salt field, and the generic data (which we don't know anything about, so better not make any assumptions). --- src/resolve/resolved-dns-packet.c | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) (limited to 'src/resolve') diff --git a/src/resolve/resolved-dns-packet.c b/src/resolve/resolved-dns-packet.c index 773691f066..955d513d7c 100644 --- a/src/resolve/resolved-dns-packet.c +++ b/src/resolve/resolved-dns-packet.c @@ -1513,6 +1513,13 @@ int dns_packet_read_rr(DnsPacket *p, DnsResourceRecord **ret, size_t *start) { if (r < 0) goto fail; + if (rr->ds.digest_size <= 0) { + /* the accepted size depends on the algorithm, but for now + just ensure that the value is greater than zero */ + r = -EBADMSG; + goto fail; + } + break; case DNS_TYPE_SSHFP: r = dns_packet_read_uint8(p, &rr->sshfp.algorithm, NULL); @@ -1526,6 +1533,14 @@ int dns_packet_read_rr(DnsPacket *p, DnsResourceRecord **ret, size_t *start) { r = dns_packet_read_memdup(p, rdlength - 2, &rr->sshfp.key, &rr->sshfp.key_size, NULL); + + if (rr->sshfp.key_size <= 0) { + /* the accepted size depends on the algorithm, but for now + just ensure that the value is greater than zero */ + r = -EBADMSG; + goto fail; + } + break; case DNS_TYPE_DNSKEY: { @@ -1557,6 +1572,14 @@ int dns_packet_read_rr(DnsPacket *p, DnsResourceRecord **ret, size_t *start) { r = dns_packet_read_memdup(p, rdlength - 4, &rr->dnskey.key, &rr->dnskey.key_size, NULL); + + if (rr->dnskey.key_size <= 0) { + /* the accepted size depends on the algorithm, but for now + just ensure that the value is greater than zero */ + r = -EBADMSG; + goto fail; + } + break; } @@ -1596,6 +1619,14 @@ int dns_packet_read_rr(DnsPacket *p, DnsResourceRecord **ret, size_t *start) { r = dns_packet_read_memdup(p, offset + rdlength - p->rindex, &rr->rrsig.signature, &rr->rrsig.signature_size, NULL); + + if (rr->rrsig.signature_size <= 0) { + /* the accepted size depends on the algorithm, but for now + just ensure that the value is greater than zero */ + r = -EBADMSG; + goto fail; + } + break; case DNS_TYPE_NSEC: @@ -1626,6 +1657,7 @@ int dns_packet_read_rr(DnsPacket *p, DnsResourceRecord **ret, size_t *start) { if (r < 0) goto fail; + /* this may be zero */ r = dns_packet_read_uint8(p, &size, NULL); if (r < 0) goto fail; @@ -1638,6 +1670,11 @@ int dns_packet_read_rr(DnsPacket *p, DnsResourceRecord **ret, size_t *start) { if (r < 0) goto fail; + if (size <= 0) { + r = -EBADMSG; + goto fail; + } + r = dns_packet_read_memdup(p, size, &rr->nsec3.next_hashed_name, &rr->nsec3.next_hashed_name_size, NULL); if (r < 0) goto fail; -- cgit v1.2.3-54-g00ecf