0
0
Fork 0
mirror of https://github.com/matrix-construct/construct synced 2024-12-26 15:33:54 +01:00

modules/s_dns_resolver: Stricter bounds checks on all operations.

This commit is contained in:
Jason Volk 2018-12-29 16:01:19 -08:00
parent 2e1828adbf
commit bccc2b5536

View file

@ -600,7 +600,7 @@ try
// Answers are parsed into this buffer // Answers are parsed into this buffer
thread_local std::array<rfc1035::answer, MAX_COUNT> an; thread_local std::array<rfc1035::answer, MAX_COUNT> an;
for(size_t i(0); i < header.ancount; ++i) for(size_t i(0); i < header.ancount; ++i)
consume(buffer, size(an[i].parse(buffer))); consume(buffer, size(an.at(i).parse(buffer)));
if(tag.opts.cache_result) if(tag.opts.cache_result)
{ {
@ -610,61 +610,78 @@ try
for(size_t i(0); i < header.ancount; ++i) for(size_t i(0); i < header.ancount; ++i)
{ {
const uint &min_ttl(seconds(cache::min_ttl).count()); const uint &min_ttl(seconds(cache::min_ttl).count());
an[i].ttl = now + std::max(an[i].ttl, min_ttl); an.at(i).ttl = now + std::max(an.at(i).ttl, min_ttl);
} }
} }
// The callback to the user will be passed a vector_view of pointers // The callback to the user will be passed a vector_view of pointers
// to this array. The actual record instances will either be located // to this array. The actual record instances will either be located
// in the cache map or placement-newed to the buffer below. // in the cache map or placement-newed to the buffer below.
thread_local const rfc1035::record *record[MAX_COUNT]; thread_local std::array<const rfc1035::record *, MAX_COUNT> record;
// This will be where we place the record instances which are dynamically // This will be where we place the record instances which are dynamically
// laid out and sized types. 512 bytes is assumed as a soft maximum for // laid out and sized types. 512 bytes is assumed as a soft maximum for
// each RR instance. // each RR instance.
thread_local uint8_t recbuf[MAX_COUNT * 512]; static const size_t recsz(512);
thread_local uint8_t recbuf[recsz * MAX_COUNT];
size_t i(0); size_t i(0);
uint8_t *pos{recbuf}; uint8_t *pos{recbuf};
for(; i < header.ancount; ++i) switch(an[i].qtype) for(; i < header.ancount; ++i) switch(an.at(i).qtype)
{ {
case 1: // A records are inserted into cache case 1: // A records are inserted into cache
{ {
using type = rfc1035::record::A;
if(!tag.opts.cache_result) if(!tag.opts.cache_result)
{ {
record[i] = new (pos) rfc1035::record::A(an[i]); if(unlikely(pos + sizeof(type) > recbuf + sizeof(recbuf)))
pos += sizeof(rfc1035::record::A); break;
record.at(i) = new (pos) type(an.at(i));
pos += sizeof(type);
continue; continue;
} }
record[i] = cache::put(qd.at(0), an[i]); record.at(i) = cache::put(qd.at(0), an.at(i));
continue; continue;
} }
case 5: case 5:
{ {
record[i] = new (pos) rfc1035::record::CNAME(an[i]); using type = rfc1035::record::CNAME;
pos += sizeof(rfc1035::record::CNAME); if(unlikely(pos + sizeof(type) > recbuf + sizeof(recbuf)))
break;
record.at(i) = new (pos) type(an.at(i));
pos += sizeof(type);
continue; continue;
} }
case 33: case 33:
{ {
using type = rfc1035::record::SRV;
if(!tag.opts.cache_result) if(!tag.opts.cache_result)
{ {
record[i] = new (pos) rfc1035::record::SRV(an[i]); if(unlikely(pos + sizeof(type) > recbuf + sizeof(recbuf)))
pos += sizeof(rfc1035::record::SRV); break;
record.at(i) = new (pos) type(an.at(i));
pos += sizeof(type);
continue; continue;
} }
record[i] = cache::put(qd.at(0), an[i]); record.at(i) = cache::put(qd.at(0), an.at(i));
continue; continue;
} }
default: default:
{ {
record[i] = new (pos) rfc1035::record(an[i]); using type = rfc1035::record;
pos += sizeof(rfc1035::record); if(unlikely(pos + sizeof(type) > recbuf + sizeof(recbuf)))
break;
record.at(i) = new (pos) type(an.at(i));
pos += sizeof(type);
continue; continue;
} }
} }
@ -675,8 +692,13 @@ try
if(tag.cb) if(tag.cb)
{ {
const vector_view<const rfc1035::record *> records(record, i); static const std::exception_ptr no_exception{};
tag.cb(std::exception_ptr{}, tag.hp, records); const vector_view<const rfc1035::record *> records
{
record.data(), i
};
tag.cb(no_exception, tag.hp, records);
} }
} }
catch(const std::exception &e) catch(const std::exception &e)