Skip to content

Possible read out of bounds in dns read

Critical
d3zd3z published GHSA-mm57-9hqw-qh44 Apr 26, 2021

Package

zephyr (west)

Affected versions

1.14.2, 2.3.0

Patched versions

2.4.0

Description

Impact

The DNS code in the Zephyr RTOS contains a possible out of bounds read which can potentially result in remote code execution.

possible read out of bounds in dns_read() in resolve.c. They unpack header id and check qr bit before they unpack the entire header.
in function dns_unpack_response_query() there is this code snippet:

/* 4 bytes more due to qtype and qclass */
offset += DNS_QTYPE_LEN + DNS_QCLASS_LEN;
if (offset > dns_msg->msg_size) {
return -ENOMEM;
}

what if (offset == dns_msg->msg_size)? we'll have a read out of bounds.
The following snippet of code appears in the function dns_unpack_answer() is called after skip_fqdn(). I think this check is faulty, since msg_size contains the actual size of the whole DNS message and it is not changed before hand as far as i've seen.

rem_size = dns_msg->msg_size - dname_len;
if (rem_size < 2 + 2 + 4 + 2) {
return -EINVAL;
}

Read out-of-bounds in dns_read() if RDLENGTH is bigger than the actual. Also we can uninitialized bytes in src:

memcpy(addr, src, address_size); 

Wrong update of the answer resource record:

/* Update the answer offset to point to the next RR (answer) */
dns_msg.answer_offset += DNS_ANSWER_PTR_LEN; 
dns_msg.answer_offset += dns_msg.response_length;

DNS_ANSWER_PTR_LEN is 12, should skip the name itself + 10, it is not always 0xc00c!!! Why not use dns_msg.response_position + RDLENGTH?
I believe this can cause underflow when trying to unpack the next answer, because the argument passed as the buffer size to skip_fqdn() is dns_msg->msg_size - dns_msg->answer_offset.
Can jump inside the name using compression pointers in dns_copy_qname(). Number of jumps is limited to ANCOUNT+1.

Patches

This has been fixed in:

For more information

If you have any questions or comments about this advisory:

embargo: 2020-11-18
zepsec: ZEPSEC-92

Severity

Critical

CVSS overall score

This score calculates overall vulnerability severity from 0 to 10 and is based on the Common Vulnerability Scoring System (CVSS).
/ 10

CVSS v3 base metrics

Attack vector
Network
Attack complexity
High
Privileges required
None
User interaction
None
Scope
Changed
Confidentiality
High
Integrity
High
Availability
High

CVSS v3 base metrics

Attack vector: More severe the more the remote (logically and physically) an attacker can be in order to exploit the vulnerability.
Attack complexity: More severe for the least complex attacks.
Privileges required: More severe if no privileges are required.
User interaction: More severe when no user interaction is required.
Scope: More severe when a scope change occurs, e.g. one vulnerable component impacts resources in components beyond its security scope.
Confidentiality: More severe when loss of data confidentiality is highest, measuring the level of data access available to an unauthorized user.
Integrity: More severe when loss of data integrity is the highest, measuring the consequence of data modification possible by an unauthorized user.
Availability: More severe when the loss of impacted component availability is highest.
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:C/C:H/I:H/A:H

CVE ID

CVE-2020-13601

Weaknesses