Security
Headlines
HeadlinesLatestCVEs

Headline

CVE-2023-0359: Missing `ipv6` nullptr-check in `handle_ra_input

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

CVE
#dos

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;

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.

CVE: Latest News

CVE-2023-50976: Transactions API Authorization by oleiman · Pull Request #14969 · redpanda-data/redpanda