From: Zbigniew Jędrzejewski-Szmek Date: Thu, 31 Jul 2014 21:42:14 +0000 (-0400) Subject: resolved: fix serialization of LOC records, check correctness X-Git-Tag: v216~320 X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=commitdiff_plain;h=afbc4f267b45480e46fbcd59e90e399bc3dc7510 resolved: fix serialization of LOC records, check correctness --- diff --git a/src/resolve/resolved-dns-packet.c b/src/resolve/resolved-dns-packet.c index 7793a014d..ba6fb3d78 100644 --- a/src/resolve/resolved-dns-packet.c +++ b/src/resolve/resolved-dns-packet.c @@ -605,15 +605,15 @@ int dns_packet_append_rr(DnsPacket *p, const DnsResourceRecord *rr, size_t *star if (r < 0) goto fail; - r = dns_packet_append_uint16(p, rr->loc.latitude, NULL); + r = dns_packet_append_uint32(p, rr->loc.latitude, NULL); if (r < 0) goto fail; - r = dns_packet_append_uint16(p, rr->loc.longitude, NULL); + r = dns_packet_append_uint32(p, rr->loc.longitude, NULL); if (r < 0) goto fail; - r = dns_packet_append_uint16(p, rr->loc.altitude, NULL); + r = dns_packet_append_uint32(p, rr->loc.altitude, NULL); break; case DNS_TYPE_SSHFP: @@ -930,6 +930,12 @@ fail: return r; } +static bool loc_size_ok(uint8_t size) { + uint8_t m = size >> 4, e = size & 0xF; + + return m <= 9 && e <= 9 && (m > 0 || e == 0); +} + int dns_packet_read_rr(DnsPacket *p, DnsResourceRecord **ret, size_t *start) { _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *rr = NULL; _cleanup_(dns_resource_key_unrefp) DnsResourceKey *key = NULL; @@ -1081,14 +1087,29 @@ int dns_packet_read_rr(DnsPacket *p, DnsResourceRecord **ret, size_t *start) { if (r < 0) goto fail; + if (!loc_size_ok(rr->loc.size)) { + r = -EBADMSG; + goto fail; + } + r = dns_packet_read_uint8(p, &rr->loc.horiz_pre, NULL); if (r < 0) goto fail; + if (!loc_size_ok(rr->loc.horiz_pre)) { + r = -EBADMSG; + goto fail; + } + r = dns_packet_read_uint8(p, &rr->loc.vert_pre, NULL); if (r < 0) goto fail; + if (!loc_size_ok(rr->loc.vert_pre)) { + r = -EBADMSG; + goto fail; + } + r = dns_packet_read_uint32(p, &rr->loc.latitude, NULL); if (r < 0) goto fail; @@ -1105,7 +1126,7 @@ int dns_packet_read_rr(DnsPacket *p, DnsResourceRecord **ret, size_t *start) { } else { dns_packet_rewind(p, pos); rr->unparseable = true; - /* fall through */ + goto unparseable; } } @@ -1133,6 +1154,7 @@ int dns_packet_read_rr(DnsPacket *p, DnsResourceRecord **ret, size_t *start) { break; default: + unparseable: r = dns_packet_read(p, rdlength, &d, NULL); if (r < 0) goto fail;