Skip to content

Infinite loop in dns_copy_qname

High
ceolin published GHSA-2qp5-c2vq-g2ww Jun 23, 2025

Package

zephyr

Affected versions

<= 4.1

Patched versions

None

Description

Summary

Possible infinite loop in subsys/net/lib/dns/dns_pack.c

int dns_copy_qname(uint8_t *buf, uint16_t *len, uint16_t size,
           struct dns_msg_t *dns_msg, uint16_t pos)
{
    uint16_t msg_size = dns_msg->msg_size;
    uint8_t *msg = dns_msg->msg;
    uint16_t lb_size;
    int rc = -EINVAL;

    *len = 0U;

    while (1) {
        if (pos >= msg_size) {
            rc = -ENOMEM;
            break;
        }

        lb_size = msg[pos];

        /* pointer */
        if (lb_size > DNS_LABEL_MAX_SIZE) {
            uint8_t mask = DNS_LABEL_MAX_SIZE;

            if (pos + 1 >= msg_size) {
                rc = -ENOMEM;
                break;
            }

            /* See: RFC 1035, 4.1.4. Message compression */
            pos = ((msg[pos] & mask) << 8) + msg[pos + 1];

            continue;
        }

If a malicious packet that causes the assignment of "pos" to be assigned to the same value it already contains, or a chain of pos assignments jumping back and forth causing the same position to be visited again, there will be an infinite loop. Read https://datatracker.ietf.org/doc/html/rfc9267#section-2 for more info on the same attack.

Impact

A denial-of-service issue that could cause an infinite loop.

Fix Recommendation

Have a separate variable containing the target position of the last jump (initialised to pos). Before every jump, make sure the target of the next jump is strictly less than the target of the previous jump. Then assign the new location to that variable and "jump" to the new target.

Note: the if (lb_size > DNS_LABEL_MAX_SIZE) { condition is also wrong according to RFC 9267, it should check that the two top bits are 0b11. If they are 0b10 or 0b01, the packet should be discarded.

Also note that the function dns_unpack_name does more or less the exact same thing (but copying to a printable string rather than a sequence of length-prefixed labels), but with a completely different code style. I suggest that the core logic of these functions are merged into one function to make the security analysis of that file easier. That second function has protection against infinite loops by putting an upper bound on loops using the loop_check variable.

Patches

For more information

If you have any questions or comments about this advisory:

embargo: 2025-06-07

Severity

High

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
Low
Privileges required
None
User interaction
None
Scope
Unchanged
Confidentiality
None
Integrity
None
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:L/PR:N/UI:N/S:U/C:N/I:N/A:H

CVE ID

CVE-2025-2962

Weaknesses