Skip to content

Stack overflow from crafted WAV with large NumChannels + div-by-zero with NumChannels=0 #22

@ByamB4

Description

@ByamB4

Hey, I was reviewing the code and found a couple of issues when reading crafted WAV files.

1. Stack overflow via alloca with large NumChannels

In tinywav_read_f() (line 242):

TW_ALLOC(int16_t, interleaved_data, tw->numChannels*len);

The default build uses alloca, so this ends up as alloca(numChannels * len * 2). The problem is that numChannels comes straight from the WAV file header and isn't validated anywhere in tinywav_open_read().

A crafted WAV file with NumChannels = 65535 causes this to try allocating ~128 MB on the stack when the caller requests even a modest number of frames (e.g. len = 1024). That's an instant crash on basically any system since stacks are typically 1-8 MB.

Even smaller values can be a problem — NumChannels = 500 with len = 1024 is already ~1 MB of stack allocation, which is borderline on many systems (especially embedded).

A simple fix would be to validate NumChannels in tinywav_open_read():

if (tw->h.NumChannels == 0 || tw->h.NumChannels > 64) { // or some reasonable max
    tinywav_close_read(tw);
    return -1;
}

2. Division by zero with NumChannels = 0

If a WAV file has NumChannels = 0 in the header, there are two division-by-zero crashes:

  • Line 220: tw->numFramesInHeader = tw->h.Subchunk2Size / (tw->numChannels * tw->sampFmt);
  • Line 244 (in tinywav_read_f): frames_read_u32 = samples_read / tw->numChannels;

Same fix as above — reject NumChannels = 0 during open.

3. Integer overflow in numChannels * len

tw->numChannels * len is int * int which can silently overflow. With the alloca path, an overflowed-small value means a tiny stack allocation followed by fread trying to fill it with the un-overflowed amount. With the malloc path you'd get a similar mismatch. This is a secondary concern after the first two though.


These only matter when loading untrusted WAV files, but since tinywav is often used in audio tooling that might open user-provided files, figured it was worth mentioning. Happy to send a PR if you'd prefer.

Metadata

Metadata

Assignees

Labels

ai-generatedThe issue was (most likely) submitted via AI, either directly or indirectly (text was written by AI)

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions