commit 9840e4cfe00cfaa5426be7ad3077abd27c0514e5
parent 6b6df4d3f49b89ea58f0b49191cf080e640923e6
Author: Lassi Pulkkinen <lassi@pulk.fi>
Date: Sat, 17 Dec 2022 07:13:33 +0200
net::dns: Don't assume rdata to be of a certain length
The existing implementation would have aborted if a record of unknown
type with an overflowing length value was encountered, and this has the
side effect of fixing that as well.
This still accepts overly large length values for fixed-size fields, but
the remainder will be properly skipped over.
Signed-off-by: Lassi Pulkkinen <lassi@pulk.fi>
Diffstat:
1 file changed, 13 insertions(+), 7 deletions(-)
diff --git a/net/dns/decode.ha b/net/dns/decode.ha
@@ -165,19 +165,25 @@ fn decode_rrecord(dec: *decoder) (rrecord | format) = {
};
fn decode_rdata(dec: *decoder, rtype: rtype, rlen: size) (rdata | format) = {
+ if (len(dec.cur) < rlen) {
+ return format;
+ };
+ let sub = decoder {
+ cur = dec.cur[..rlen],
+ buf = dec.buf,
+ };
+ dec.cur = dec.cur[rlen..];
switch (rtype) {
case rtype::A =>
- return decode_a(dec);
+ return decode_a(&sub);
case rtype::AAAA =>
- return decode_aaaa(dec);
+ return decode_aaaa(&sub);
case rtype::MX =>
- return decode_mx(dec);
+ return decode_mx(&sub);
case rtype::TXT =>
- return decode_txt(dec);
+ return decode_txt(&sub);
case =>
- let buf = dec.cur[..rlen];
- dec.cur = dec.cur[rlen..];
- return buf: unknown_rdata;
+ return sub.cur: unknown_rdata;
};
};