hexwave_segv.c
hexwave_write_proof.c
In hexwave_init(), the product oversample * halfwidth overflows a 32-bit int.
This causes all internal buffers to be severely undersized, but the
deinterleave loop uses a post-clamp width, resulting in a large heap overflow
write.
Trigger:
hexwave_init(65536, 65536, user_buffer);
Root cause:
halfwidth = width/2 // 32768
half = halfwidth * oversample // INT_MIN (overflow)
n = 2*half + 1 // 1
step = malloc(n * sizeof(float)) // 4 bytes instead of ~8 GB
ramp = malloc(n * sizeof(float)) // 4 bytes
blep_buffer_count = width*(oversample+1) // 65536 (truncated)
blep_buffer = malloc(blep_count*4) // 256 KB
// width clamped AFTER all allocations
if (width > 64) width = 64;
// deinterleave loop: 4,194,368 writes
for (j = 0; j < oversample+1; ++j)
for (i = 0; i < width; ++i) {
blep_buffer[jwidth+i] = step[j+ioversample]; // OOB
blamp_buffer[jwidth+i] = ramp[j+ioversample]; // OOB
}
Impact: ~15.75 MB heap overflow write past a 256 KB allocation.
Verified with ASAN and mmap write-proof.
Fix: move the width clamp to the start of hexwave_init():
void hexwave_init(int width, int oversample, float *user_buffer) {
if (width > STB_HEXWAVE_MAX_BLEP_LENGTH)
width = STB_HEXWAVE_MAX_BLEP_LENGTH;
int halfwidth = width / 2;
// ...
PoC attached: hexwave_segv.c, hexwave_write_proof.c
gcc -fsanitize=address -g -O0 -o hexwave_segv hexwave_segv.c -lm
./hexwave_segv
hexwave_segv.c
hexwave_write_proof.c
In hexwave_init(), the product oversample * halfwidth overflows a 32-bit int.
This causes all internal buffers to be severely undersized, but the
deinterleave loop uses a post-clamp width, resulting in a large heap overflow
write.
Trigger:
hexwave_init(65536, 65536, user_buffer);
Root cause:
halfwidth = width/2 // 32768
half = halfwidth * oversample // INT_MIN (overflow)
n = 2*half + 1 // 1
step = malloc(n * sizeof(float)) // 4 bytes instead of ~8 GB
ramp = malloc(n * sizeof(float)) // 4 bytes
blep_buffer_count = width*(oversample+1) // 65536 (truncated)
blep_buffer = malloc(blep_count*4) // 256 KB
// width clamped AFTER all allocations
if (width > 64) width = 64;
// deinterleave loop: 4,194,368 writes
for (j = 0; j < oversample+1; ++j)
for (i = 0; i < width; ++i) {
blep_buffer[jwidth+i] = step[j+ioversample]; // OOB
blamp_buffer[jwidth+i] = ramp[j+ioversample]; // OOB
}
Impact: ~15.75 MB heap overflow write past a 256 KB allocation.
Verified with ASAN and mmap write-proof.
Fix: move the width clamp to the start of hexwave_init():
void hexwave_init(int width, int oversample, float *user_buffer) {
if (width > STB_HEXWAVE_MAX_BLEP_LENGTH)
width = STB_HEXWAVE_MAX_BLEP_LENGTH;
int halfwidth = width / 2;
// ...
PoC attached: hexwave_segv.c, hexwave_write_proof.c
gcc -fsanitize=address -g -O0 -o hexwave_segv hexwave_segv.c -lm
./hexwave_segv