An issue was discovered in SoX 14.4.2. In xmalloc.h, there is an integer overflow on the result of multiplication fed into the lsx_valloc macro that wraps malloc. When the buffer is allocated, it is smaller than expected, leading to a heap-based buffer overflow in channels_start in remix.c. Reference: https://sourceforge.net/p/sox/bugs/320
Created sox tracking bugs for this issue: Affects: fedora-all [bug 1678289]
So, for this flaw, we get to lsx_realloc with the following newsize: ``` │30 void *lsx_realloc(void *ptr, size_t newsize) │ │31 { │ >│32 if (ptr && newsize == 0) { │ │33 free(ptr); │ │34 return NULL; │ │35 } (gdb) print newsize $11 = 17179869184 ``` The system tries, and fails, to allocate 17 gigabytes and we exit. We get to realloc with the large size via: ``` │232 unsigned in_per_out = (effp->in_signal.channels + │ │233 num_out_channels - 1 - j) / num_out_channels; │ >│234 lsx_valloc(p->out_specs[j].in_specs, in_per_out); (gdb) print effp->in_signal.channels $12 = 1073741824 ``` The size grows via the lsx_valloc macro: ```c #define lsx_valloc(v,n) v = lsx_malloc((n)*sizeof(*(v))) ``` On a 64-bit platform, we have 1073741824 * 16 via the sizeof *in_specs ``` (gdb) print sizeof(*(p->out_specs[j].in_specs)) $14 = 16 ``` which gets us the 17179869184 value that runs us out of memory. To potentially exploit this, we'd need to wrap around the calculation. (gdb) ptype in_per_out type = unsigned int Max size on our platform is going to be 4294967295. * 16 is 68719476720, which will fit nicely in size_t. So I believe this is only potentially exploitable on 32-bit platforms. This could still be considered a denial of service on 64-bit (maybe, arguably, etc.), so I'll leave this open as valid for now.