Skip to content

Commit f89cc9f

Browse files
authored
Validate high order two bits of first dns label octet (#494)
1 parent 638bf9b commit f89cc9f

File tree

2 files changed

+18
-8
lines changed

2 files changed

+18
-8
lines changed

src/dns.cpp

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -86,14 +86,18 @@ void DNS::skip_to_dname_end(InputMemoryStream& stream) const {
8686
break;
8787
}
8888
else {
89-
if ((value & 0xc0)) {
90-
// This is an offset label, skip the second byte and we're done
89+
const uint8_t offset_discriminator = value & 0xc0;
90+
if (offset_discriminator == 0xc0) {
91+
// This is an offset pointer, skip the second byte and we're done
9192
stream.skip(1);
9293
break;
9394
}
94-
else {
95+
else if (offset_discriminator == 0) {
9596
// This is an actual label, skip its contents
9697
stream.skip(value);
98+
} else {
99+
// high order two bits of the first octet of a label must be either 11 or 00
100+
throw malformed_packet();
97101
}
98102
}
99103
}

tests/src/dns_test.cpp

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -571,6 +571,7 @@ TEST_F(DNSTest, BadLabelSize) {
571571

572572
// add bad length
573573
const size_t bad_label_len{0x80};
574+
const size_t label_offset = payload_sz;
574575
payload[payload_sz++] = bad_label_len;
575576

576577
// fill label for incorrect length and terminate
@@ -590,13 +591,18 @@ TEST_F(DNSTest, BadLabelSize) {
590591
payload + payload_sz);
591592
payload_sz += sizeof(type_class);
592593

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);
594+
// invalid high two bits of label first octest is detected early now
596595
try {
597-
const auto queries{packet.queries()};
596+
const DNS packet(payload, payload_sz);
598597
FAIL();
599-
} catch (dns_decompression_pointer_out_of_bounds& oob) {
598+
} catch (malformed_packet& mp) {
599+
SUCCEED();
600+
}
601+
602+
// check the other invalid value of high two bits in label size
603+
payload[label_offset] = 0x10;
604+
try {
605+
const DNS packet(payload, payload_sz);
600606
FAIL();
601607
} catch (malformed_packet& mp) {
602608
SUCCEED();

0 commit comments

Comments
 (0)