hare

[hare] The Hare programming language
git clone https://git.torresjrjr.com/hare.git
Log | Files | Refs | README | LICENSE

commit 6b6df4d3f49b89ea58f0b49191cf080e640923e6
parent fa782ec3f9f9c697092f31688977ac56e73ac0ae
Author: Lassi Pulkkinen <lassi@pulk.fi>
Date:   Sat, 17 Dec 2022 07:13:32 +0200

net::dns: Rework decode_name

Drop unnecessary recursion
Add checks for end of message, reference loops, invalid utf8, length limit

This also fixes a memory leak by removing the relevant allocation entirely.
The approach used for the reference loop check is borrowed from musl.

Signed-off-by: Lassi Pulkkinen <lassi@pulk.fi>

Diffstat:
Mnet/dns/decode.ha | 40++++++++++++++++++++++++++++++----------
1 file changed, 30 insertions(+), 10 deletions(-)

diff --git a/net/dns/decode.ha b/net/dns/decode.ha @@ -1,5 +1,6 @@ // License: MPL-2.0 // (c) 2021 Drew DeVault <sir@cmpwn.com> +// (c) 2022 Lassi Pulkkinen <lassi@pulk.fi> use ascii; use endian; use fmt; @@ -92,24 +93,43 @@ fn decode_op(in: u16, out: *op) void = { fn decode_name(dec: *decoder) ([]str | format) = { let names: []str = []; - for (true) { + let totalsize = 0z; + let sub = decoder { + buf = dec.buf, + ... + }; + for (let i = 0z; i < len(dec.buf); i += 2) { + if (len(dec.cur) < 1) { + return format; + }; const z = dec.cur[0]; if (z & 0b11000000 == 0b11000000) { const offs = decode_u16(dec)? & ~0b1100000000000000u16; - const sub = decoder { - buf = dec.buf, - cur = dec.buf[offs..], - ... + if (len(dec.buf) < offs) { + return format; }; - append(names, decode_name(&sub)?...); - break; + sub.cur = dec.buf[offs..]; + dec = &sub; + continue; }; dec.cur = dec.cur[1..]; + totalsize += z + 1; + if (totalsize > 255) { + return format; + }; if (z == 0) { - break; + return names; }; - const name = strings::fromutf8(dec.cur[..z])!; + if (len(dec.cur) < z) { + return format; + }; + const name = match (strings::fromutf8(dec.cur[..z])) { + case let name: str => + yield name; + case => + return format; + }; dec.cur = dec.cur[z..]; if (!ascii::validstr(name)) { return format; @@ -117,7 +137,7 @@ fn decode_name(dec: *decoder) ([]str | format) = { append(names, strings::dup(name)); }; - return names; + return format; }; fn decode_question(dec: *decoder) (question | format) = {