mirror of
https://github.com/mfontanini/libtins
synced 2026-01-23 02:35:57 +01:00
dns: bad label size interpreted as decompression pointer (#466)
Co-authored-by: Bill Willcox <billwcorp@gmail.com>
This commit is contained in:
@@ -342,7 +342,7 @@ uint32_t DNS::compose_name(const uint8_t* ptr, char* out_ptr) const {
|
|||||||
throw dns_decompression_pointer_loops();
|
throw dns_decompression_pointer_loops();
|
||||||
}
|
}
|
||||||
// It's an offset
|
// It's an offset
|
||||||
if ((*ptr & 0xc0)) {
|
if (((*ptr & 0xc0) == 0xc0)) {
|
||||||
if (TINS_UNLIKELY(ptr + sizeof(uint16_t) > end)) {
|
if (TINS_UNLIKELY(ptr + sizeof(uint16_t) > end)) {
|
||||||
throw malformed_packet();
|
throw malformed_packet();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -551,3 +551,54 @@ TEST_F(DNSTest, SOARecordSerialize) {
|
|||||||
EXPECT_EQ(0x8ad71928U, r2.expire());
|
EXPECT_EQ(0x8ad71928U, r2.expire());
|
||||||
EXPECT_EQ(0x1ad92871U, r2.minimum_ttl());
|
EXPECT_EQ(0x1ad92871U, r2.minimum_ttl());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(DNSTest, BadLabelSize) {
|
||||||
|
const uint8_t header[] = {
|
||||||
|
0x45, 0xbc, // ID
|
||||||
|
0x81, 0x80, // response, recursion desired, recursion available, no error
|
||||||
|
0x00, 0x01, // QDCOUNT
|
||||||
|
0x00, 0x00, // ANCOUNT
|
||||||
|
0x00, 0x00, // NSCOUNT
|
||||||
|
0x00, 0x00 // ARCOUNT
|
||||||
|
};
|
||||||
|
size_t payload_sz{sizeof(header)};
|
||||||
|
uint8_t payload[512];
|
||||||
|
|
||||||
|
// copy header
|
||||||
|
std::copy(header,
|
||||||
|
header + payload_sz,
|
||||||
|
payload);
|
||||||
|
|
||||||
|
// add bad length
|
||||||
|
const size_t bad_label_len{0x80};
|
||||||
|
payload[payload_sz++] = bad_label_len;
|
||||||
|
|
||||||
|
// fill label for incorrect length and terminate
|
||||||
|
std::fill(payload + payload_sz,
|
||||||
|
payload + payload_sz + bad_label_len,
|
||||||
|
'a');
|
||||||
|
payload_sz += bad_label_len;
|
||||||
|
payload[payload_sz++] = 0x0;
|
||||||
|
|
||||||
|
// add type and class
|
||||||
|
const uint8_t type_class[] = {
|
||||||
|
0x00, 0x01,
|
||||||
|
0x00, 0x01
|
||||||
|
};
|
||||||
|
std::copy(type_class,
|
||||||
|
type_class + sizeof(type_class),
|
||||||
|
payload + payload_sz);
|
||||||
|
payload_sz += sizeof(type_class);
|
||||||
|
|
||||||
|
// SUCCEED moves from dns_decompression_pointer_out_of_bounds to malformed_packet after fix
|
||||||
|
const DNS packet(payload, payload_sz);
|
||||||
|
EXPECT_EQ(packet.questions_count(), 1);
|
||||||
|
try {
|
||||||
|
const auto queries{packet.queries()};
|
||||||
|
FAIL();
|
||||||
|
} catch (dns_decompression_pointer_out_of_bounds& oob) {
|
||||||
|
FAIL();
|
||||||
|
} catch (malformed_packet& mp) {
|
||||||
|
SUCCEED();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user