Skip to content

Commit 633caad

Browse files
bwillcoxbwillcoxpubfork
authored andcommitted
dns: bad label size interpreted as decompression pointer (mfontanini#466)
Co-authored-by: Bill Willcox <[email protected]>
1 parent 5d64361 commit 633caad

File tree

2 files changed

+52
-1
lines changed

2 files changed

+52
-1
lines changed

src/dns.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -342,7 +342,7 @@ uint32_t DNS::compose_name(const uint8_t* ptr, char* out_ptr) const {
342342
throw dns_decompression_pointer_loops();
343343
}
344344
// It's an offset
345-
if ((*ptr & 0xc0)) {
345+
if (((*ptr & 0xc0) == 0xc0)) {
346346
if (TINS_UNLIKELY(ptr + sizeof(uint16_t) > end)) {
347347
throw malformed_packet();
348348
}

tests/src/dns_test.cpp

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -551,3 +551,54 @@ TEST_F(DNSTest, SOARecordSerialize) {
551551
EXPECT_EQ(0x8ad71928U, r2.expire());
552552
EXPECT_EQ(0x1ad92871U, r2.minimum_ttl());
553553
}
554+
555+
TEST_F(DNSTest, BadLabelSize) {
556+
const uint8_t header[] = {
557+
0x45, 0xbc, // ID
558+
0x81, 0x80, // response, recursion desired, recursion available, no error
559+
0x00, 0x01, // QDCOUNT
560+
0x00, 0x00, // ANCOUNT
561+
0x00, 0x00, // NSCOUNT
562+
0x00, 0x00 // ARCOUNT
563+
};
564+
size_t payload_sz{sizeof(header)};
565+
uint8_t payload[512];
566+
567+
// copy header
568+
std::copy(header,
569+
header + payload_sz,
570+
payload);
571+
572+
// add bad length
573+
const size_t bad_label_len{0x80};
574+
payload[payload_sz++] = bad_label_len;
575+
576+
// fill label for incorrect length and terminate
577+
std::fill(payload + payload_sz,
578+
payload + payload_sz + bad_label_len,
579+
'a');
580+
payload_sz += bad_label_len;
581+
payload[payload_sz++] = 0x0;
582+
583+
// add type and class
584+
const uint8_t type_class[] = {
585+
0x00, 0x01,
586+
0x00, 0x01
587+
};
588+
std::copy(type_class,
589+
type_class + sizeof(type_class),
590+
payload + payload_sz);
591+
payload_sz += sizeof(type_class);
592+
593+
// SUCCEED moves from dns_decompression_pointer_out_of_bounds to malformed_packet after fix
594+
const DNS packet(payload, payload_sz);
595+
EXPECT_EQ(packet.questions_count(), 1);
596+
try {
597+
const auto queries{packet.queries()};
598+
FAIL();
599+
} catch (dns_decompression_pointer_out_of_bounds& oob) {
600+
FAIL();
601+
} catch (malformed_packet& mp) {
602+
SUCCEED();
603+
}
604+
}

0 commit comments

Comments
 (0)