WavPack: WavPack crashes with SEGFAULT

Hello!

This bug was found by Crusher (fuzzer developing in ISP RAS), thanks to following colleagues: Vitalii Akolzin, Shamil Kurmangaleev, Maxim Mishechkin, Fedor Nis’kov, Ivan Gulakov, Denis Straghkov, Andrey Fedotov, Alexey Vishnyakov, Daniil Kutz, Alexander Novikov.

Product version

Commit 940a8b7f35205efbd5d64a88875481a7dbfa7e52 (latest commit on master at current moment).

Environment

Ubuntu 16.04/18.04

To reproduce

  1. Extract crash.wav from crash.wav.tar.gz
  2. Run:
wavpack -y crash.wav

Program crashes with SEGFAULT.

Error message:

 WAVPACK  Hybrid Lossless Audio Compressor  Linux Version 5.3.2
 Copyright (c) 1998 - 2020 David Bryant.  All Rights Reserved.

creating crash.wv,Segmentation fault (core dumped)

Valgrind output:

creating crash.wv,==29284== Invalid write of size 4
==29284==    at 0x122C08: WavpackPackSamples (pack_utils.c:662)
==29284==    by 0x1111ED: pack_audio (wavpack.c:2407)
==29284==    by 0x1111ED: pack_file (wavpack.c:1911)
==29284==    by 0x10B792: main (wavpack.c:1278)
==29284==  Address 0x559d3f0 is 0 bytes after a block of size 162,800 alloc'd
==29284==    at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==29284==    by 0x12282B: WavpackPackInit (pack_utils.c:561)
==29284==    by 0x110FE6: pack_audio (wavpack.c:2323)
==29284==    by 0x110FE6: pack_file (wavpack.c:1911)
==29284==    by 0x10B792: main (wavpack.c:1278)
==29284== 
==29284== Invalid write of size 4
==29284==    at 0x122C17: WavpackPackSamples (pack_utils.c:663)
==29284==    by 0x1111ED: pack_audio (wavpack.c:2407)
==29284==    by 0x1111ED: pack_file (wavpack.c:1911)
==29284==    by 0x10B792: main (wavpack.c:1278)
==29284==  Address 0x559d3f4 is 4 bytes after a block of size 162,800 alloc'd
==29284==    at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==29284==    by 0x12282B: WavpackPackInit (pack_utils.c:561)
==29284==    by 0x110FE6: pack_audio (wavpack.c:2323)
==29284==    by 0x110FE6: pack_file (wavpack.c:1911)
==29284==    by 0x10B792: main (wavpack.c:1278)
==29284== 
   0% done...--29284-- VALGRIND INTERNAL ERROR: Valgrind received a signal 11 (SIGSEGV) - exiting
--29284-- si_code=1;  Faulting address: 0x7F0563D49E;  sp: 0x1002dade30

valgrind: the 'impossible' happened:
   Killed by fatal signal

host stacktrace:
==29284==    at 0x58053139: ??? (in /usr/lib/valgrind/memcheck-amd64-linux)
==29284==    by 0x5800BA84: ??? (in /usr/lib/valgrind/memcheck-amd64-linux)
==29284==    by 0x5800BC66: ??? (in /usr/lib/valgrind/memcheck-amd64-linux)
==29284==    by 0x5809F785: ??? (in /usr/lib/valgrind/memcheck-amd64-linux)
==29284==    by 0x580AED50: ??? (in /usr/lib/valgrind/memcheck-amd64-linux)

sched status:
  running_tid=1

Thread 1: status = VgTs_Runnable (lwpid 29284)
==29284==    at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==29284==    by 0x1211E2: pack_streams (pack_utils.c:955)
==29284==    by 0x122DB1: WavpackFlushSamples (pack_utils.c:727)
==29284==    by 0x112537: pack_audio (wavpack.c:2444)
==29284==    by 0x112537: pack_file (wavpack.c:1911)
==29284==    by 0x10B792: main (wavpack.c:1278)

Analysis

  1. In https://github.com/dbry/WavPack/blob/940a8b7f35205efbd5d64a88875481a7dbfa7e52/src/pack_utils.c#L561 malloc’s argument overflows size_t type and results in small positive number. So, only a short memory region is allocated.

  2. Then https://github.com/dbry/WavPack/blob/940a8b7f35205efbd5d64a88875481a7dbfa7e52/src/pack_utils.c#L612 dptr now points to address in previously allocated region

  3. Finally https://github.com/dbry/WavPack/blob/940a8b7f35205efbd5d64a88875481a7dbfa7e52/src/pack_utils.c#L662 we write in memory by dptr pointer. But in one moment dptr points to memory outside of allocated region. Segmentation fault.

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Reactions: 1
  • Comments: 16 (6 by maintainers)

Commits related to this issue

Most upvoted comments

First of all, thank you @wakolzin for finding and reporting this issue! This is now fixed in the master branch.

I have also carefully analyzed the issue and I believe that this is an extremely low risk from a security perspective. The buffer overflow could be exploited to corrupt the next heap entry and possibly force the next malloc to return an arbitrary address, but unfortunately that next malloc is for the compressed audio block and there’s no method for the attacker to control what gets written there. Another complicating factor is that the compressor modifies the audio data “in-place” during decorrrelation, so again there’s no way to control the final contents. I’m certainly no expert in this, but I think it would be extraordinarily difficult, if not impossible, to create an exploit for this overrun.

But more problematic, even if it were possible to create an exploit, it would be nearly impossible to trigger it from a practical standpoint. The WavPack command-line program is not a default application for WAV files (or any file type) and is not supplied by default in any distro. Therefore the attacker would have to convince a user to install the command-line program, manually download the maliciously crafted file, and attempt, using the terminal, to compress it using WavPack. If you can get someone to do that, there are far simpler ways of gaining control of their system.

@dbry This issue was the only I know about.