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