1
0
mirror of https://github.com/mfontanini/libtins synced 2026-01-23 02:35:57 +01:00

Removed access to potentially invalid positions on vector.

This commit is contained in:
Matias Fontanini
2014-11-12 21:11:01 -08:00
parent 0ba05f9d1a
commit 3b126ca02b
2 changed files with 63 additions and 52 deletions

View File

@@ -327,7 +327,7 @@ const uint8_t* DNS::compose_name(const uint8_t *ptr, char *out_ptr) const {
std::memcpy(&index, ptr, sizeof(uint16_t)); std::memcpy(&index, ptr, sizeof(uint16_t));
index = Endian::be_to_host(index) & 0x3fff; index = Endian::be_to_host(index) & 0x3fff;
// Check that the offset is neither too low or too high // Check that the offset is neither too low or too high
if(index < 0x0c || &records_data[index - 0x0c] >= ptr) if(index < 0x0c || (&records_data[0] + (index - 0x0c)) >= ptr)
throw malformed_packet(); throw malformed_packet();
// We've probably found the end of the original domain name. Save it. // We've probably found the end of the original domain name. Save it.
if(end_ptr == 0) if(end_ptr == 0)
@@ -494,80 +494,91 @@ uint8_t *DNS::update_dname(uint8_t *ptr, uint32_t threshold, uint32_t offset) {
// Updates offsets in domain names inside records. // Updates offsets in domain names inside records.
// No length checks, records are already valid. // No length checks, records are already valid.
void DNS::update_records(uint32_t &section_start, uint32_t num_records, uint32_t threshold, uint32_t offset) { void DNS::update_records(uint32_t &section_start, uint32_t num_records, uint32_t threshold, uint32_t offset) {
uint8_t *ptr = &records_data[section_start]; if(records_data.size() >= section_start) {
for(uint32_t i = 0; i < num_records; ++i) { uint8_t *ptr = &records_data[section_start];
ptr = update_dname(ptr, threshold, offset); for(uint32_t i = 0; i < num_records; ++i) {
uint16_t type; ptr = update_dname(ptr, threshold, offset);
std::memcpy(&type, ptr, sizeof(uint16_t)); uint16_t type;
type = Endian::be_to_host(type); std::memcpy(&type, ptr, sizeof(uint16_t));
ptr += sizeof(uint16_t) * 2 + sizeof(uint32_t); type = Endian::be_to_host(type);
uint16_t size; ptr += sizeof(uint16_t) * 2 + sizeof(uint32_t);
std::memcpy(&size, ptr, sizeof(uint16_t)); uint16_t size;
size = Endian::be_to_host(size); std::memcpy(&size, ptr, sizeof(uint16_t));
ptr += sizeof(uint16_t); size = Endian::be_to_host(size);
if(type == MX) {
ptr += sizeof(uint16_t); ptr += sizeof(uint16_t);
size -= sizeof(uint16_t); if(type == MX) {
ptr += sizeof(uint16_t);
size -= sizeof(uint16_t);
}
if(contains_dname(type)) {
update_dname(ptr, threshold, offset);
}
ptr += size;
} }
if(contains_dname(type)) {
update_dname(ptr, threshold, offset);
}
ptr += size;
} }
section_start += offset; section_start += offset;
} }
DNS::queries_type DNS::queries() const { DNS::queries_type DNS::queries() const {
queries_type output; queries_type output;
const uint8_t *ptr = &records_data[0], *end = &records_data[answers_idx]; if(!records_data.empty()) {
char buffer[256]; const uint8_t *ptr = &records_data[0],
uint16_t tmp_query_type; *end = &records_data[0] + answers_idx;
uint16_t tmp_query_class; char buffer[256];
while(ptr < end) { uint16_t tmp_query_type;
ptr = compose_name(ptr, buffer); uint16_t tmp_query_class;
if(ptr + sizeof(uint16_t) * 2 > end) while(ptr < end) {
throw malformed_packet(); ptr = compose_name(ptr, buffer);
std::memcpy(&tmp_query_type, ptr, sizeof(uint16_t)); if(ptr + sizeof(uint16_t) * 2 > end)
std::memcpy(&tmp_query_class, ptr + 2, sizeof(uint16_t)); throw malformed_packet();
output.push_back( std::memcpy(&tmp_query_type, ptr, sizeof(uint16_t));
Query( std::memcpy(&tmp_query_class, ptr + 2, sizeof(uint16_t));
buffer, output.push_back(
(QueryType)Endian::be_to_host(tmp_query_type), Query(
(QueryClass)Endian::be_to_host(tmp_query_class) buffer,
) (QueryType)Endian::be_to_host(tmp_query_type),
); (QueryClass)Endian::be_to_host(tmp_query_class)
ptr += sizeof(uint16_t) * 2; )
);
ptr += sizeof(uint16_t) * 2;
}
} }
return output; return output;
} }
DNS::resources_type DNS::answers() const { DNS::resources_type DNS::answers() const {
resources_type res; resources_type res;
convert_records( if(records_data.size() >= authority_idx) {
&records_data[answers_idx], convert_records(
&records_data[authority_idx], &records_data[answers_idx],
res &records_data[authority_idx],
); res
);
}
return res; return res;
} }
DNS::resources_type DNS::authority() const { DNS::resources_type DNS::authority() const {
resources_type res; resources_type res;
convert_records( if(records_data.size() >= additional_idx) {
&records_data[authority_idx], convert_records(
&records_data[additional_idx], &records_data[authority_idx],
res &records_data[additional_idx],
); res
);
}
return res; return res;
} }
DNS::resources_type DNS::additional() const { DNS::resources_type DNS::additional() const {
resources_type res; resources_type res;
convert_records( if(records_data.size() >= additional_idx) {
&records_data[additional_idx], convert_records(
&records_data[records_data.size()], &records_data[additional_idx],
res &records_data[records_data.size()],
); res
);
}
return res; return res;
} }

View File

@@ -77,7 +77,7 @@ PDU *IPv4Stream::allocate_pdu() const {
} }
return Internals::pdu_from_flag( return Internals::pdu_from_flag(
static_cast<Constants::IP::e>(transport_proto), static_cast<Constants::IP::e>(transport_proto),
&buffer[0], buffer.empty() ? 0 : &buffer[0],
buffer.size() buffer.size()
); );
} }