static void _write_block(int fd, unsigned bs, unsigned i)
{
char block[bs];
char *buf = block;
buf += snprintf(buf, bs, "|%03u|", i); // VULN: snprintf() returns the total length of the string it tried to create, which may be larger than bs
memset(buf, _get_char(i), &block[bs] - buf); // VULN: buf can point past the block buffer, in addition &block[bs] - buf would be negative and become a large unsigned value
block[bs - 1] = '\n';
vfs_write(fd, block, bs);
}
raptor@blumenkraft Research % cat ret1.c
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
static char _get_char(unsigned i)
{
i %= 62; /* a-z, A-Z, 0..9, -> 62 characters */
if (i < 10) {
return '0' + i;
}
i -= 10;
if (i <= 'z' - 'a') {
return 'a' + i;
}
i -= 1 + 'z' - 'a';
return 'A' + i;
}
static void _write_block(unsigned bs, unsigned i)
{
char block[bs];
char *buf = block;
buf += snprintf(buf, bs, "|%03u|", i); // VULN: unsafe use of return value
memset(buf, _get_char(i), &block[bs] - buf); // VULN: oob memory write, size becomes a large unsigned value
block[bs - 1] = '\n';
}
int main(int argc, char **argv)
{
if (argc < 3)
return 1;
_write_block(atoi(argv[1]), atoi(argv[2]));
return 0;
}
raptor@blumenkraft Research % make ret1
cc ret1.c -o ret1
raptor@blumenkraft Research % ./ret1 5 10
raptor@blumenkraft Research % ./ret1 5 1000000
zsh: segmentation fault ./ret1 5 1000000
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.
Summary
I spotted an unsafe use of the return value of
snprintf()
that leads to an out-of-bounds memory access in RIOT source code at:https://github.com/RIOT-OS/RIOT/blob/master/sys/shell/cmds/vfs.c#L747-L749
Details
The
snprintf()
API function returns the number of characters (excluding the terminating NUL byte) which would have been written to the destination string if enough space had been available. If an attacker is able to craft input so that the final string would become larger thanbs
, they can exploit this bug to cause a buffer overflow.Please refer to the marked lines below:
PoC
I put together a quick proof-of-concept to demonstrate this issue:
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.