Skip to content

Null Pointer dereference during fragment forwarding

High
chrysn published GHSA-69h9-vj5r-xcg6 Apr 24, 2023

Package

RIOT-OS

Affected versions

< 2022.10

Patched versions

2022.10

Description

Impact

RIOT-OS contains a network stack with the ability to process 6LoWPAN frames. An attacker can send a crafted frame to the device resulting in a NULL pointer dereference. During forwarding of a fragment an uninitialized entry in the reassembly buffer is used. The NULL pointer dereference triggers a hard fault exception resulting in denial of service.

Patches

Workarounds

  • Disabling support for fragmented IP datagrams, or
  • Backport the patches listed above

For more information

If you have any questions or comments about this advisory:

Bug Details

Missing source address leads to NULL pointer dereference

NULL pointer dereference in gnrc_sixlowpan_dispatch_send due to unchecked use of return value from gnrc_netif_get_by_pid (source):

void gnrc_sixlowpan_dispatch_send(gnrc_pktsnip_t *pkt, void *context,
                                  unsigned page)
{
    (void)context;
    (void)page;
    assert(pkt->type == GNRC_NETTYPE_NETIF);
    gnrc_netif_hdr_t *hdr = pkt->data;
    if (gnrc_netif_send(gnrc_netif_get_by_pid(hdr->if_pid), pkt) < 1) {

The return value is NULL because hdr->if_pid is zero, which is defined as invalid pid.
The function is called in gnrc_sixlowpan_frag_minfwd_forward, where the netif header is build from the vrbe (source):

    tmp = _netif_hdr_from_vrbe(vrbe);
    ...
    pkt = gnrc_pkt_prepend(pkt, tmp);
    gnrc_sixlowpan_dispatch_send(pkt, NULL, page);

The function is called from _forward_frag, which just passes the vrbe through, which is then called from _rbuf_add.
There the vrb is retrieved via gnrc_sixlowpan_frag_vrb_get (source):

    (entry.vrb = gnrc_sixlowpan_frag_vrb_get(src, netif_hdr->src_l2addr_len,
                                             datagram_tag)) != NULL) {
    ...
    if (_forward_frag(pkt, sizeof(sixlowpan_frag_n_t), entry.vrb,
                  page) < 0) {

The problem here is that the netif_hdr->src_l2addr_len is zero and an empty vrb entry is defined as having super.src_len == 0.
This leads to the situation that gnrc_sixlowpan_frag_vrb_get returns an uninitialized vrb entry.

The same bug can be triggered via another path: gnrc_sixlowpan_frag_sfr_recv -> _forward_rfrag -> _send_frame

Cause of missing address in netif header

The netif_hdr is created by the link layer, in this case the IEEE 802.15.4 netif layer.
In _recv the function _make_netif_hdr is called to set the values in the header (source):

    netif_hdr = _make_netif_hdr(mhr);

Here the source and destination addresses are retrieved and written to the netif_hdr (source):

    dst_len = ieee802154_get_dst(mhr, dst, &_pan_tmp);
    src_len = ieee802154_get_src(mhr, src, &_pan_tmp);
        if ((dst_len < 0) || (src_len < 0)) {
        DEBUG("_make_netif_hdr: unable to get addresses\n");
        return NULL;
    }
    /* allocate space for header */
    snip = gnrc_netif_hdr_build(src, (size_t)src_len, dst, (size_t)dst_len);

These functions decode the Frame Type header and if the Destination/Source Addressing Mode specifies that the address is not present a length of zero is returned.
Thus the addresses are absent from the packet forwarded to the 6LoWPAN layer.

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-2023-24818

Credits