dbry / WavPack

WavPack encode/decode library, command-line programs, and several plugins
BSD 3-Clause "New" or "Revised" License
371 stars 67 forks source link

A heap-buffer-overflow in wvtest #161

Closed blu3sh0rk closed 1 year ago

blu3sh0rk commented 1 year ago

Desctiption

A heap-buffer-overflow has occurred when running program wvtest in function MD5_Final at WavPack/cli/md5.c:283:2

Version

$ git log
commit fcef67cfa110e74806fb1dd7c9f3e583f831542b (HEAD -> master, origin/master, origin/HEAD)
Author: David Bryant <david@wavpack.com>
Date:   Wed Mar 1 18:24:26 2023 -0800

    import_id3.c: do not reject ID3v2 tags with footers

$./wavpack -h

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

Steps to reproduce

git clone https://github.com/dbry/WavPack
cd WavPack/
mkdir check_build && cd check_build
cmake ../ -DCMAKE_C_COMPILER=clang  -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_C_FLAGS="-fsanitize=address" -DCMAKE_CXX_FLAGS="-fsanitize=address"
make -j8

./wvtest --seektest  POC1

 WVTEST  libwavpack Tester/Exerciser for WavPack  Linux Version 5.6.2
 Copyright (c) 2020 David Bryant.  All Rights Reserved.

-------------------- file: POC1 --------------------
=================================================================
==2389827==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x620000000ec0 at pc 0x0000004e2529 bp 0x7ffddde1c490 sp 0x7ffddde1c488
WRITE of size 1 at 0x620000000ec0 thread T0
    #0 0x4e2528 in MD5_Final /home/lzy/fuzz/oss/WavPack/cli/md5.c:283:2
    #1 0x4cdcf1 in seeking_test /home/lzy/fuzz/oss/WavPack/cli/wvtest.c:365:13
    #2 0x4cdcf1 in main /home/lzy/fuzz/oss/WavPack/cli/wvtest.c:250:24
    #3 0x7f3042afe082 in __libc_start_main /build/glibc-KZwQYS/glibc-2.31/csu/../csu/libc-start.c:308:16
    #4 0x42054d in _start (/home/lzy/fuzz/oss/WavPack/check_build/wvtest+0x42054d)

0x620000000ec0 is located 0 bytes to the right of 3648-byte region [0x620000000080,0x620000000ec0)
allocated by thread T0 here:
    #0 0x49b7ad in malloc (/home/lzy/fuzz/oss/WavPack/check_build/wvtest+0x49b7ad)
    #1 0x4cdbf4 in seeking_test /home/lzy/fuzz/oss/WavPack/cli/wvtest.c:337:23
    #2 0x4cdbf4 in main /home/lzy/fuzz/oss/WavPack/cli/wvtest.c:250:24
    #3 0x7f3042afe082 in __libc_start_main /build/glibc-KZwQYS/glibc-2.31/csu/../csu/libc-start.c:308:16

SUMMARY: AddressSanitizer: heap-buffer-overflow /home/lzy/fuzz/oss/WavPack/cli/md5.c:283:2 in MD5_Final
Shadow bytes around the buggy address:
  0x0c407fff8180: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c407fff8190: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c407fff81a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c407fff81b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c407fff81c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x0c407fff81d0: 00 00 00 00 00 00 00 00[fa]fa fa fa fa fa fa fa
  0x0c407fff81e0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c407fff81f0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c407fff8200: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c407fff8210: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c407fff8220: 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
==2389827==ABORTING

POC

https://github.com/blu3sh0rk/Fuzzing-crash/blob/main/wvtest/POC1

Code at WavPack/cli/md5.c:283:2

    memset(&ctx->buffer[used], 0, available - 8);

    ctx->lo <<= 3;
    OUT(&ctx->buffer[56], ctx->lo)
    OUT(&ctx->buffer[60], ctx->hi)

    body(ctx, ctx->buffer, 64);

    OUT(&result[0], ctx->a)   <--283 line
    OUT(&result[4], ctx->b)
    OUT(&result[8], ctx->c)
    OUT(&result[12], ctx->d) 

    memset(ctx, 0, sizeof(*ctx));
}

#endif

Environment:

Ubuntu 20.04.3 LTS \n \l

IMPACT

Potentially causing DoS and RCE

dbry commented 1 year ago

Hi, and thanks for reporting this!

The problem was that the seektest expects a valid WavPack file, not the output of a fuzzer. It's purpose is to test the seeking function of libwavpack with varying, but valid, files. In this case the WavPack file was corrupt and did not decode correctly, and the manner in which it failed was not being checked for. I have pushed a fix for this including that check, but there could certainly be other bugs in the tester, not to mention memory leaks.

Since wvtest is not a user-facing program, nor even available in any distribution or package, I do not consider this a security issue. And I also believe that even if a bug was found in the libwavpack seeking code, it would not be a great security risk either because of the difficulty of triggering it outside of the lab.

I would be very curious as to how you think this issue might be exploited to cause a DoS or RCE. :smile: