CVE-2023-33975: Out-of-bounds Write (CWE-787)
value: RIOT-OS, an operating system for Internet of Things (IoT) devices, contains a network stack with the ability to process 6LoWPAN frames. In version 2023.01 and prior, an attacker can send a crafted frame to the device resulting in an out of bounds write in the packet buffer. The overflow can be used to corrupt other packets and the allocator metadata. Corrupting a pointer will easily lead to denial of service. While carefully manipulating the allocator metadata gives an attacker the possibility to write data to arbitrary locations and thus execute arbitrary code. This issue is fixed in pull request 19680. As a workaround, disable support for fragmented IP datagrams.
CWE description: The product writes data past the end, or before the beginning, of the intended buffer.
CVSS v3 base score: 9.8
Published: 2023-05-30T18:15Z
Repository: https://github.com/RIOT-OS/RIOT
Language: C
Files changed: sys/net/gnrc/network_layer/sixlowpan/frag/rb/gnrc_sixlowpan_frag_rb.c
Commit date: 2023-05-30 16:44:09 +0200
Commit message: gnrc_sixlowpan_frag_rb: fix OOB write in _rbuf_add

Diff: diff --git a/sys/net/gnrc/network_layer/sixlowpan/frag/rb/gnrc_sixlowpan_frag_rb.c b/sys/net/gnrc/network_layer/sixlowpan/frag/rb/gnrc_sixlowpan_frag_rb.c
index d406f605766..1112969719e 100644
--- a/sys/net/gnrc/network_layer/sixlowpan/frag/rb/gnrc_sixlowpan_frag_rb.c
+++ b/sys/net/gnrc/network_layer/sixlowpan/frag/rb/gnrc_sixlowpan_frag_rb.c
@@ -459,10 +459,23 @@ static int _rbuf_add(gnrc_netif_hdr_t *netif_hdr, gnrc_pktsnip_t *pkt,
                     }
                 }
                 else if (IS_USED(MODULE_GNRC_SIXLOWPAN_FRAG_SFR) &&
                          sixlowpan_sfr_rfrag_is(pkt->data)) {
                     entry.super->datagram_size--;
+                    /* Check, if fragment is still small enough to fit datagram size.
+                     * `offset` is 0, as this is the first fragment so it does not have to be added
+                     * here. */
+                    if (frag_size > entry.super->datagram_size) {
+                        DEBUG_PUTS(
+                           "6lo rfrag: fragment too big for resulting datagram, "
+                           "discarding datagram\n"
+                        );
+                        gnrc_pktbuf_release(entry.rbuf->pkt);
+                        gnrc_pktbuf_release(pkt);
+                        gnrc_sixlowpan_frag_rb_remove(entry.rbuf);
+                        return RBUF_ADD_ERROR;
+                    }
                 }
             }
         }
         if (IS_USED(MODULE_GNRC_SIXLOWPAN_FRAG_MINFWD) ||
             IS_USED(MODULE_GNRC_SIXLOWPAN_FRAG_SFR)) {

Fixed code:                     /* Check, if fragment is still small enough to fit datagram size.
                     * `offset` is 0, as this is the first fragment so it does not have to be added
                     * here. */
                    if (frag_size > entry.super->datagram_size) {
                        DEBUG_PUTS(
                           "6lo rfrag: fragment too big for resulting datagram, "
                           "discarding datagram\n"
                        );
                        gnrc_pktbuf_release(entry.rbuf->pkt);
                        gnrc_pktbuf_release(pkt);
                        gnrc_sixlowpan_frag_rb_remove(entry.rbuf);
                        return RBUF_ADD_ERROR;
                    }