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

Credits