Skip to content

Missing `ipv6` nullptr-check in `handle_ra_input

Moderate
ceolin published GHSA-c7fq-vqm6-v5pf Jul 10, 2023

Package

zephyr (west)

Affected versions

<= 3.2

Patched versions

None

Description

Summary

A missing nullptr-check in handle_ra_input can cause a nullptr-deref.

Description

The reachable_time update in handle_ra_input is missing a nullptr-check for net_pkt_iface(pkt)->config.ip.ipv6 before calling net_if_ipv6_set_reachable_time:

if (reachable_time && reachable_time <= MAX_REACHABLE_TIME && (net_if_ipv6_get_reachable_time(net_pkt_iface(pkt)) != reachable_time)) {
    net_if_ipv6_set_base_reachable_time(net_pkt_iface(pkt), reachable_time);
    net_if_ipv6_set_reachable_time(net_pkt_iface(pkt)->config.ip.ipv6);
}

if (reachable_time && reachable_time <= MAX_REACHABLE_TIME &&
(net_if_ipv6_get_reachable_time(net_pkt_iface(pkt)) !=
reachable_time)) {
net_if_ipv6_set_base_reachable_time(net_pkt_iface(pkt),
reachable_time);
net_if_ipv6_set_reachable_time(
net_pkt_iface(pkt)->config.ip.ipv6);
}

The ipv6 interface pointer is passed into net_if_ipv6_calc_reachable_time in net_if_ipv6_set_reachable_time:

ipv6->reachable_time = net_if_ipv6_calc_reachable_time(ipv6);

/**
* @brief Set IPv6 reachable time for a given interface. This requires
* that base reachable time is set for the interface.
*
* @param ipv6 IPv6 address configuration
*/
static inline void net_if_ipv6_set_reachable_time(struct net_if_ipv6 *ipv6)
{
#if defined(CONFIG_NET_NATIVE_IPV6)
ipv6->reachable_time = net_if_ipv6_calc_reachable_time(ipv6);
#endif
}

The ipv6 interface pointer is then used without an additional check in net_if_ipv6_calc_reachable_time:

min_reachable = (MIN_RANDOM_NUMER * ipv6->base_reachable_time) / MIN_RANDOM_DENOM;
max_reachable = (MAX_RANDOM_NUMER * ipv6->base_reachable_time) / MAX_RANDOM_DENOM;

zephyr/subsys/net/ip/net_if.c

Lines 2756 to 2774 in 98580f1

uint32_t net_if_ipv6_calc_reachable_time(struct net_if_ipv6 *ipv6)
{
uint32_t min_reachable, max_reachable;
k_mutex_lock(&lock, K_FOREVER);
min_reachable = (MIN_RANDOM_NUMER * ipv6->base_reachable_time)
/ MIN_RANDOM_DENOM;
max_reachable = (MAX_RANDOM_NUMER * ipv6->base_reachable_time)
/ MAX_RANDOM_DENOM;
k_mutex_unlock(&lock);
NET_DBG("min_reachable:%u max_reachable:%u", min_reachable,
max_reachable);
return min_reachable +
sys_rand32_get() % (max_reachable - min_reachable);
}

However the other usages in handle_ra_input do check for a nullptr:

  • net_if_ipv6_get_reachable_time:

    if (!iface->config.ip.ipv6) { return 0; }

    /**
    * @brief Get IPv6 reachable timeout specified for a given interface
    *
    * @param iface Network interface
    *
    * @return Reachable timeout
    */
    static inline uint32_t net_if_ipv6_get_reachable_time(struct net_if *iface)
    {
    #if defined(CONFIG_NET_NATIVE_IPV6)
    if (!iface->config.ip.ipv6) {
    return 0;
    }
    return iface->config.ip.ipv6->reachable_time;
    #else
    return 0;
    #endif
    }

  • net_if_ipv6_set_base_reachable_time

    if (!iface->config.ip.ipv6) { return; }

    /**
    * @brief Set IPv6 reachable time for a given interface
    *
    * @param iface Network interface
    * @param reachable_time New reachable time
    */
    static inline void net_if_ipv6_set_base_reachable_time(struct net_if *iface,
    uint32_t reachable_time)
    {
    #if defined(CONFIG_NET_NATIVE_IPV6)
    if (!iface->config.ip.ipv6) {
    return;
    }
    iface->config.ip.ipv6->base_reachable_time = reachable_time;
    #endif
    }

Impact

  • Potentially cause a Denial of Service.
    • Note: We are able to cause a DoS in Zephyr 2.2.0 with fuzzing, but did not try to reproduce in current versions.

Proposed Fix

  • Add a nullptr check in net_if_ipv6_set_reachable_time or add a wrapper function with a check similar to net_if_ipv6_get_reachable_time or net_if_ipv6_set_base_reachable_time.

Severity

Moderate

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
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:H/PR:N/UI:N/S:U/C:N/I:N/A:H

CVE ID

CVE-2023-0359

Weaknesses

Improper Input Validation

The product receives input or data, but it does not validate or incorrectly validates that the input has the properties that are required to process the data safely and correctly. Learn more on MITRE.