Security
Headlines
HeadlinesLatestCVEs

Headline

CVE-2023-24818: Null Pointer dereference during fragment forwarding

RIOT-OS, an operating system that supports Internet of Things devices, contains a network stack with the ability to process 6LoWPAN frames. Prior to version 2022.10, 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. Version 2022.10 fixes this issue. As a workaround, disable support for fragmented IP datagrams or apply the patches manually.

CVE
#dos

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

  • master #1, #2, #3
  • 2022.10 #1, #2, #3

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:

  • Open an issue in RIOT
  • Email us at RIOT-security

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.

CVE: Latest News

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