From: Alan T. DeKok Date: Tue, 12 Oct 2021 19:52:27 +0000 (-0400) Subject: add marker array for tracking where labels can point to X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=8bfd0fd901f7ced17523e226024e3a0a3420bb10;p=thirdparty%2Ffreeradius-server.git add marker array for tracking where labels can point to --- diff --git a/src/lib/util/dns.c b/src/lib/util/dns.c index f3b836627ae..b6e487a7a6c 100644 --- a/src/lib/util/dns.c +++ b/src/lib/util/dns.c @@ -113,12 +113,25 @@ static int dns_label_add(fr_dns_labels_t *lb, uint8_t const *start, uint8_t cons return 0; } +static void dns_label_mark(fr_dns_labels_t *lb, uint8_t const *p) +{ + if (!lb || !lb->mark) return; + + fr_assert(p >= (lb->start + 12)); /* can't point to the packet header */ + fr_assert(!lb->end || (p < lb->end)); + + lb->mark[p - lb->start] = 1; +} + + static bool dns_pointer_valid(fr_dns_labels_t *lb, uint16_t offset) { int i; if (!lb) return true; /* we have no idea, so allow it */ + if (lb->mark) return (lb->mark[offset] != 0); + for (i = 0; i < lb->num; i++) { FR_PROTO_TRACE("Checking block %d %u..%u against %u", i, lb->blocks[i].start, lb->blocks[i].end, offset); @@ -1063,6 +1076,8 @@ ssize_t fr_dns_label_uncompressed_length(uint8_t const *packet, uint8_t const *b */ if ((p + *p + 1) > end) goto overflow; + dns_label_mark(lb, p); + /* * Account for the '.' on every label after the * first one. diff --git a/src/lib/util/dns.h b/src/lib/util/dns.h index 31be362fbc8..f639c156f2e 100644 --- a/src/lib/util/dns.h +++ b/src/lib/util/dns.h @@ -34,6 +34,8 @@ typedef struct { typedef struct { uint8_t const *start; //!< start of packet + uint8_t const *end; //!< end of the packet + uint8_t *mark; //!< markup buffer int num; //!< number of used labels int max; //! maximum number of labels fr_dns_block_t blocks[]; //!< array holding "max" labels diff --git a/src/protocols/dns/decode.c b/src/protocols/dns/decode.c index fcbd4a3b890..6ec8c9a0280 100644 --- a/src/protocols/dns/decode.c +++ b/src/protocols/dns/decode.c @@ -696,9 +696,14 @@ static ssize_t fr_dns_decode_proto(TALLOC_CTX *ctx, fr_pair_list_t *out, uint8_t lb->blocks[0].start = 12; lb->blocks[0].end = 12; lb->num = 1; + + memset(packet_ctx->lb->mark, 0, talloc_array_length(packet_ctx->lb->mark)); } else { packet_ctx->lb = fr_dns_labels_init(packet_ctx, data, 256); fr_assert(packet_ctx->lb != NULL); + + packet_ctx->lb->end = data + data_len; + packet_ctx->lb->mark = talloc_zero_array(packet_ctx->lb, uint8_t, 65535); } return fr_dns_decode(ctx, out, data, data_len, packet_ctx);