dns-packet: limit the number of jumps during packet decompression
So far we didn't limit the number of jumps when decompressing a DNS packet. This can lead to some extra work with specially crafted packets that send a staircase of thousands of descending compression pointers, which can then be amplified by referencing such staircase from thousands of names. Given that legitimate DNS packets need only a handful of jumps in the compression chains, let's limit the number of jumps per a single name to 256 (the same limit as, for example, Unbound currently has). Reported by opensec-intelligence (OpenSec).
This commit is contained in:
committed by
Luca Boccassi
parent
726cc309b4
commit
efa16c7f31
@@ -1583,7 +1583,7 @@ int dns_packet_read_name(
|
||||
assert(p);
|
||||
|
||||
_cleanup_(rewind_dns_packet) DnsPacketRewinder rewinder = REWINDER_INIT(p);
|
||||
size_t after_rindex = 0, jump_barrier = p->rindex;
|
||||
size_t after_rindex = 0, jump_barrier = p->rindex, jumps = 0;
|
||||
_cleanup_free_ char *name = NULL;
|
||||
bool first = true;
|
||||
size_t n = 0, m = 0;
|
||||
@@ -1643,6 +1643,9 @@ int dns_packet_read_name(
|
||||
if (ptr < DNS_PACKET_HEADER_SIZE || ptr >= jump_barrier)
|
||||
return -EBADMSG;
|
||||
|
||||
if (jumps++ >= DNS_COMPRESSION_JUMPS_MAX)
|
||||
return -EBADMSG;
|
||||
|
||||
if (after_rindex == 0)
|
||||
after_rindex = p->rindex;
|
||||
|
||||
|
||||
@@ -51,6 +51,9 @@ assert_cc(sizeof(DnsPacketHeader) == 12);
|
||||
/* With EDNS0 we can use larger packets, default to 1232, which is what is commonly used */
|
||||
#define DNS_PACKET_UNICAST_SIZE_LARGE_MAX 1232u
|
||||
|
||||
/* Maximum number of compression pointers we are willing to follow while decoding a single name */
|
||||
#define DNS_COMPRESSION_JUMPS_MAX 256U
|
||||
|
||||
typedef struct DnsPacket {
|
||||
unsigned n_ref;
|
||||
DnsProtocol protocol;
|
||||
|
||||
Reference in New Issue
Block a user