Project: libsndfile (libsndfile/libsndfile), language: c++
Vulnerability instance: libsndfile.cve-2021-3246
Sanitizer: address

================= Bug Report (1/1) ==================
## Source: GitHub Issue
## URL: https://github.com/libsndfile/libsndfile/issues/687
## Description:
Issue: libsndfile/libsndfile#687
Title: heap-buffer-overflow in in msadpcm_decode_block
State: closed
Created by: andreafioraldi
Created at: 2021-01-15 10:43:55+00:00
Labels: Bug

Issue Body:
Hi,
fuzzing sndfile-info with AFL++ I found a heap-buffer-overflow in in msadpcm_decode_block /home/andreaf/real/libsndfile/src/ms_adpcm.c:279

I'm on an x86-64 Ubuntu 20.04 with Clang 10.

The AddressSanitizer report is the following:

```
=================================================================
==24888==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x621000001238 at pc 0x0000005ebedc bp 0x7ffced651bd0 sp 0x7ffced651bc8
WRITE of size 2 at 0x621000001238 thread T0
    #0 0x5ebedb in msadpcm_decode_block /home/andreaf/libsndfile/src/ms_adpcm.c:279:31
    #1 0x5e9cf8 in wavlike_msadpcm_init /home/andreaf/libsndfile/src/ms_adpcm.c:171:3
    #2 0x566da9 in wav_open /home/andreaf/libsndfile/src/wav.c:258:14
    #3 0x4cc6d2 in psf_open_file /home/andreaf/libsndfile/src/sndfile.c:3080:13
    #4 0x4caa5e in sf_open /home/andreaf/libsndfile/src/sndfile.c:359:9
    #5 0x4c57dd in cart_dump /home/andreaf/libsndfile/programs/sndfile-info.c:479:14
    #6 0x4c36c3 in main /home/andreaf/libsndfile/programs/sndfile-info.c:96:13
    #7 0x7f114ca61bf6 in __libc_start_main /build/glibc-S9d2JN/glibc-2.27/csu/../csu/libc-start.c:310
    #8 0x41b4c9 in _start (/home/andreaf/libsndfile/programs/sndfile-info+0x41b4c9)

0x621000001238 is located 0 bytes to the right of 4408-byte region [0x621000000100,0x621000001238)
allocated by thread T0 here:
    #0 0x493d82 in calloc (/home/andreaf/libsndfile/programs/sndfile-info+0x493d82)
    #1 0x5e90b4 in wavlike_msadpcm_init /home/andreaf/libsndfile/src/ms_adpcm.c:138:27
    #2 0x566da9 in wav_open /home/andreaf/libsndfile/src/wav.c:258:14
    #3 0x4cc6d2 in psf_open_file /home/andreaf/libsndfile/src/sndfile.c:3080:13
    #4 0x4caa5e in sf_open /home/andreaf/libsndfile/src/sndfile.c:359:9
    #5 0x4c57dd in cart_dump /home/andreaf/libsndfile/programs/sndfile-info.c:479:14
    #6 0x4c36c3 in main /home/andreaf/libsndfile/programs/sndfile-info.c:96:13
    #7 0x7f114ca61bf6 in __libc_start_main /build/glibc-S9d2JN/glibc-2.27/csu/../csu/libc-start.c:310

SUMMARY: AddressSanitizer: heap-buffer-overflow /home/andreaf/libsndfile/src/ms_adpcm.c:279:31 in msadpcm_decode_block
Shadow bytes around the buggy address:
  0x0c427fff81f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c427fff8200: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c427fff8210: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c427fff8220: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c427fff8230: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x0c427fff8240: 00 00 00 00 00 00 00[fa]fa fa fa fa fa fa fa fa
  0x0c427fff8250: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c427fff8260: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c427fff8270: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c427fff8280: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c427fff8290: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07 
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
  Shadow gap:              cc
==24888==ABORTING
```

To reproduce on git master:

```
export CC='clang-10 -fsanitize=address'
export CFLAGS='-g'
./configure --disable-shared
make
./programs/sndfile-info --cart ./sndfile_heap_overflow
```

The testcase that triggers the bug is (decompress it before):

[sndfile_heap_overflow.tar.gz](https://github.com/libsndfile/libsndfile/files/5819990/sndfile_heap_overflow.tar.gz)



Comments:
Comment by evpobr on 2021-01-16 05:16:30+00:00:
Hi @andreafioraldi, thanks for report.

---

Comment by zodf0055980 on 2021-01-25 07:23:35+00:00:
I think this problem is about` BlockAlign` is not match `NumChannels * BitsPerSample / 8`.
In this poc, BlockAlign = 1280, NumChannels = 128, BitsPerSample (Bit Width) = 1.
In `wavpack`, it have [this check](https://github.com/dbry/WavPack/blob/bb175a626586b0cc7afab78ef5fcc2cc98afa861/cli/riff.c#L189) and this POC not pass.
```
            if (!WaveHeader.NumChannels || WaveHeader.NumChannels > 256 ||
                WaveHeader.BlockAlign / WaveHeader.NumChannels < (config->bits_per_sample + 7) / 8 ||
                WaveHeader.BlockAlign / WaveHeader.NumChannels > 4 ||
                WaveHeader.BlockAlign % WaveHeader.NumChannels)
                    supported = FALSE;
```

---

Comment by zodf0055980 on 2021-01-26 21:01:56+00:00:
Oop, maybe `blockalign == bitwidth * channels / 8` is only for WAVE_FORMAT_PCM .
https://github.com/libsndfile/libsndfile/blob/251a435566bd798a45629425f3a61df8d61e3ba1/src/wavlike.c#L150-L155
In the `make test` test case, ima_adpcm.wav doesn't have this feature.
```
File : ima_adpcm.wav
Length : 4668
RIFF : 4660
WAVE
fmt  : 20
  Format        : 0x11 => WAVE_FORMAT_IMA_ADPCM
  Channels      : 1
  Sample Rate   : 16000
  Block Align   : 512
  Bit Width     : 4
  Extra Bytes   : 2
  Samples/Block : 1017
  Bytes/sec     : 8055 (should be 15)
fact : 4
  frames  : 9153
data : 4608
End
```

---

Comment by tamir-ben on 2021-07-21 11:57:47+00:00:
Hi, is there a plan of fixing the issue?
Or is the fix for #697 sufficient for this issue as well? That is, https://github.com/libsndfile/libsndfile/commit/9e0e55f8bfa60bddca083ff85699f855c91c42e7

---

Comment by evpobr on 2021-07-21 14:41:50+00:00:
Hi @galaktipus , it was fixed: https://oss-fuzz.com/testcase-detail/5696502087024640. I guess i forgot to close this issue.

You can use master branch, we tagged unofficial release 1.1.0beta1 there.

---

Comment by ajakk on 2021-07-21 21:20:07+00:00:
> Hi @galaktipus , it was fixed: https://oss-fuzz.com/testcase-detail/5696502087024640. I guess i forgot to close this issue.
> 
> You can use master branch, we tagged unofficial release 1.1.0beta1 there.

I don't see a tag, maybe it wasn't pushed? That link is also behind a login, can you point directly to a fix?

---

Comment by evpobr on 2021-07-22 04:48:19+00:00:
@galaktipus , actually you can use master branch.

@SoapGentoo , could you create tag for 1.1.0beta1?

---

Comment by SoapGentoo on 2021-07-22 10:30:19+00:00:
@evpobr sorry, forgot to push for beta1, pushed now

---

Comment by carnil on 2021-07-23 18:54:11+00:00:
CVE-2021-3246 appears to have been assigned for this issue.

---

Comment by evpobr on 2021-07-24 07:47:57+00:00:
@carnil , thanks.

---

Comment by krisfed on 2021-08-11 14:47:26+00:00:
Thank you very much for fixing this! Just to confirm, is this the [commit](https://github.com/libsndfile/libsndfile/commit/deb669ee8be55a94565f6f8a6b60890c2e7c6f32#diff-3bb9934284df08f6cc86dfd9badec919ff89d0967670e6247415064e3ca30c96 ) and the pull request https://github.com/libsndfile/libsndfile/pull/713  that fixes this issue? 

I would also appreciate any information about the approximate timeline for the next official release... I think this fix is not in 1.0.31, and we are somewhat limited in ability to address CVEs by upgrading to an unofficial beta releases or by patching. So any info about the plans for the next release would be very helpful!

---

Comment by evpobr on 2021-08-12 05:59:23+00:00:
> Thank you very much for fixing this! Just to confirm, is this the [commit](https://github.com/libsndfile/libsndfile/commit/deb669ee8be55a94565f6f8a6b60890c2e7c6f32#diff-3bb9934284df08f6cc86dfd9badec919ff89d0967670e6247415064e3ca30c96) and the pull request #713 that fixes this issue?

Yes.

> I would also appreciate any information about the approximate timeline for the next official release... I think this fix is not in 1.0.31, and we are somewhat limited in ability to address CVEs by upgrading to an unofficial beta releases or by patching. So any info about the plans for the next release would be very helpful!

Unfortunately, there are no exact dates. I hope we will release 1.1.0 this year. We're waiting for @arthurt to finish whatever he wanted about the MP3 format, but he is probably very busy at work or maybe resting. We'll wait for him to respond.

---

Comment by arthurt on 2021-08-13 02:40:09+00:00:
Uh oh, I thought we were waiting on something else!

---

Comment by evpobr on 2021-08-13 04:46:25+00:00:
No :smile:

---

Comment by DerDakon on 2021-08-30 09:15:43+00:00:
The CVE states that only 1.0.30 is affected. I think that e4cc9d350ab162374ebe2e88d712dba70e511a3b introduced the incomplete check, which is in 1.0.26. But given that there was no check before I assume that even older versions are affected. Can you confirm this, at least that >1.0.26 are affected, and update the CVE information, please?

---

Comment by andreafioraldi on 2021-08-30 10:01:10+00:00:
I found the bug fuzzing the 1.0.28 fyi

---

Comment by ajakk on 2021-08-30 13:03:22+00:00:
> The CVE states that only 1.0.30 is affected. I think that [e4cc9d3](https://github.com/libsndfile/libsndfile/commit/e4cc9d350ab162374ebe2e88d712dba70e511a3b) introduced the incomplete check, which is in 1.0.26. But given that there was no check before I assume that even older versions are affected. Can you confirm this, at least that >1.0.26 are affected, and update the CVE information, please?

Anyone can request CVE data to be updated:

https://cveform.mitre.org

---

Comment by evpobr on 2021-08-30 17:03:42+00:00:
Hi everybody. It would be nice to update CVE. Maybe it is better to wait for 1.1.0 with fix and then update description? 

---

Comment by KamicDemon on 2022-01-18 07:56:49+00:00:
Hello all,
I'm testing a black box Linux system that supposedly uses a version of libsndfile vulnerable to the CVEs related to this issue. Has made a .wav file PoC that would induce a crash indicative of vulnerability available? It would be helpful to test systems that don't have arbitrary execution access enabled on them. Thank you!

---

Comment by evpobr on 2022-01-18 08:40:22+00:00:
Hi @KamicDemon 

> Has made a .wav file PoC that would induce a crash indicative of vulnerability available?

Hmm, i didn't quite understand, do you need a text file or did you create it?

---

Comment by ajakk on 2022-01-19 00:36:08+00:00:
> Hello all, I'm testing a black box Linux system that supposedly uses a version of libsndfile vulnerable to the CVEs related to this issue. Has made a .wav file PoC that would induce a crash indicative of vulnerability available? It would be helpful to test systems that don't have arbitrary execution access enabled on them. Thank you!

The test case is in the original report.

---

Comment by KamicDemon on 2022-01-19 03:37:53+00:00:
> Hi @KamicDemon
> 
> > Has made a .wav file PoC that would induce a crash indicative of vulnerability available?
> 
> Hmm, i didn't quite understand, do you need a text file or did you create it?

Hi, thanks for the reply. I may have misunderstood the nature of the vulnerability in question. I assumed it could be triggered simply by playing a crafted WAV file on a device using the vulnerable version of Libsnd. I was asking if anyone had made a .wav PoC file, but forgot to type out the word "anyone"

Attachments:
https://github.com/libsndfile/libsndfile/files/5819990/sndfile_heap_overflow.tar.gz

Commit References:
deb669ee8be55a94565f6f8a6b60890c2e7c6f32
9e0e55f8bfa60bddca083ff85699f855c91c42e7
3bb9934284df08f6cc86dfd9badec919ff89d096
bb175a626586b0cc7afab78ef5fcc2cc98afa861
e4cc9d350ab162374ebe2e88d712dba70e511a3b
251a435566bd798a45629425f3a61df8d61e3ba1

Build script:
#!/bin/bash
# Default build script template for C/C++ projects
set -eu

# Define configuration options
CONFIG_OPTS="--disable-shared"
CMAKE_OPTS="-DCMAKE_BUILD_TYPE=Debug"
MAKE_OPTS="-j$(nproc)"
BUILD_DIR="build"

# 1. Run build preparation scripts if they exist
for prep_script in buildconf autogen.sh bootstrap; do
  if [ -x "$prep_script" ]; then
    echo "Running $prep_script..."
    ./$prep_script
    break
  elif [ -f "$prep_script" ]; then
    echo "Found $prep_script but it's not executable, setting permissions..."
    chmod +x $prep_script
    ./$prep_script
    break
  fi
done

# 2. Handle different build systems
if [ -f "configure" ]; then
  echo "Found configure script, running with options: $CONFIG_OPTS"
  ./configure $CONFIG_OPTS

  echo "Building with make $MAKE_OPTS"
  make $MAKE_OPTS
elif [ -f "CMakeLists.txt" ]; then
  echo "Found CMakeLists.txt, using CMake build system"
  mkdir -p $BUILD_DIR
  cd $BUILD_DIR
  cmake $CMAKE_OPTS ..
  make $MAKE_OPTS
elif [ -f "Makefile" ] || [ -f "makefile" ]; then
  echo "Found Makefile, building with make $MAKE_OPTS"
  make $MAKE_OPTS
elif [ -f "meson.build" ]; then
  echo "Found meson.build, using Meson build system"
  mkdir -p $BUILD_DIR
  meson setup $BUILD_DIR .
  cd $BUILD_DIR
  ninja
elif [ -f "GNUmakefile" ]; then
  echo "Found GNUmakefile, building with make $MAKE_OPTS"
  make $MAKE_OPTS
elif [ -d ".git" ] && [ -f "Makefile.am" ]; then
  echo "Found Makefile.am, running autoreconf"
  autoreconf -i
  ./configure $CONFIG_OPTS
  make $MAKE_OPTS
else
  echo "WARNING: No recognized build system found!"
  echo "Trying generic approach:"
  
  # Try to detect common source patterns and compile them
  if ls *.c >/dev/null 2>&1 || ls *.cpp >/dev/null 2>&1 || ls *.cc >/dev/null 2>&1; then
    echo "Found C/C++ source files, attempting direct compilation"
    if ls *.cpp >/dev/null 2>&1 || ls *.cc >/dev/null 2>&1; then
      CXX=${CXX:-g++}
      echo "Compiling C++ sources with $CXX"
      $CXX -g -O1 -fsanitize=address -fno-omit-frame-pointer -o main *.cpp *.cc 2>/dev/null || true
    elif ls *.c >/dev/null 2>&1; then
      CC=${CC:-gcc}
      echo "Compiling C sources with $CC"
      $CC -g -O1 -fsanitize=address -fno-omit-frame-pointer -o main *.c 2>/dev/null || true
    fi
  fi
fi

Dockerfile:
FROM hwiwonlee/secb.base:latest
RUN git clone https://github.com/libsndfile/libsndfile libsndfile
RUN git -C libsndfile checkout 68958f9c9199dad97dcd10700df3746b2cd9b8a3
WORKDIR $SRC/libsndfile
COPY build.sh $SRC/

Additional files: