Skip to content

Integer wraparound and buffer overflow in RIOT /drivers/mtd_emulated/mtd_emulated.c

Low
Teufelchen1 published GHSA-r87w-9vw9-f7cx Apr 25, 2024

Package

RIOT

Affected versions

<= 2023.10

Patched versions

None

Description

Summary

I spotted an integer wraparound in a size check that leads to a buffer overflow in RIOT source code at:
https://github.com/RIOT-OS/RIOT/blob/master/drivers/mtd_emulated/mtd_emulated.c#L112-L117

Details

If an attacker is able to provide arbitrary values for the num and sector arguments to the _erase_sector() function, they can cause an integer wraparound to bypass the size check and cause a buffer overflow.

Please refer to the marked lines below:

static int _erase_sector(mtd_dev_t *dev, uint32_t sector, uint32_t num)
{
    mtd_emulated_t *mtd = (mtd_emulated_t *)dev;

    (void)mtd;
    assert(mtd);

    if (/* sector must not exceed the number of sectors */
        (sector >= mtd->base.sector_count) ||
        /* sector + num must not exceed the number of sectors */
        ((sector + num) > mtd->base.sector_count)) { // VULN: integer wraparound in size check
        return -EOVERFLOW;
    }

    memset(mtd->memory + (sector * (mtd->base.pages_per_sector * mtd->base.page_size)),
           0xff, num * (mtd->base.pages_per_sector * mtd->base.page_size)); // VULN: buffer overflow

    return 0;
}

PoC

I put together a quick proof-of-concept to demonstrate this issue:

raptor@blumenkraft Research % cat wraparound5.c
#include <stdio.h>
#include <stdlib.h>
#include <inttypes.h>

#define SECTOR_COUNT 256

static int _erase_sector(uint32_t sector, uint32_t num)
{
    if (/* sector must not exceed the number of sectors */
        (sector >= SECTOR_COUNT) ||
        /* sector + num must not exceed the number of sectors */
        ((sector + num) > SECTOR_COUNT)) { // VULN: wraparound
        printf("OVERFLOW\n");
	return 1;
    }

    printf("sector + num = %"PRIu32"\n", sector + num);

    return 0;
}

int main(int argc, char **argv)
{
	if (argc < 3)
		return 1;

	return _erase_sector(atoi(argv[1]), atoi(argv[2]));
}
raptor@blumenkraft Research % make wraparound5
cc     wraparound5.c   -o wraparound5
raptor@blumenkraft Research % ./wraparound5 250 10
OVERFLOW
raptor@blumenkraft Research % ./wraparound5 250 4294967295
sector + num = 249

Impact

If the input above is attacker-controlled and crosses a security boundary, the impact of the buffer overflow vulnerability could range from denial of service to (less likely in this case) arbitrary code execution.

Severity

Low

CVE ID

No known CVE

Weaknesses

Integer Overflow or Wraparound

The product performs a calculation that can produce an integer overflow or wraparound, when the logic assumes that the resulting value will always be larger than the original value. This can introduce other weaknesses when the calculation is used for resource management or execution control. Learn more on MITRE.

Integer Overflow to Buffer Overflow

The product performs a calculation to determine how much memory to allocate, but an integer overflow can occur that causes less memory to be allocated than expected, leading to a buffer overflow. Learn more on MITRE.

Credits