Bug 1678288 (CVE-2019-8355) - CVE-2019-8355 sox: integer overflow in xmalloc.h
Summary: CVE-2019-8355 sox: integer overflow in xmalloc.h
Alias: CVE-2019-8355
Product: Security Response
Classification: Other
Component: vulnerability
Version: unspecified
Hardware: All
OS: Linux
Target Milestone: ---
Assignee: Red Hat Product Security
QA Contact:
Depends On: 1678289 1680086
Blocks: 1678305
TreeView+ depends on / blocked
Reported: 2019-02-18 12:47 UTC by Dhananjay Arunesh
Modified: 2021-10-27 03:25 UTC (History)
4 users (show)

Fixed In Version:
Doc Type: If docs needed, set a value
Doc Text:
Clone Of:
Last Closed: 2021-10-27 03:25:16 UTC

Attachments (Terms of Use)

Description Dhananjay Arunesh 2019-02-18 12:47:05 UTC
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.


Comment 1 Dhananjay Arunesh 2019-02-18 12:47:16 UTC
Created sox tracking bugs for this issue:

Affects: fedora-all [bug 1678289]

Comment 2 Scott Gayou 2019-02-22 17:00:13 UTC
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:

#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.

Note You need to log in before you can comment on or make changes to this bug.