ralph-irving / faad2

Freeware Advanced Audio (AAC) Decoder with ALAC, stdin and seeking support.
Other
3 stars 4 forks source link

Crash when parsing malformed AAC file #6

Closed retpoline closed 2 years ago

retpoline commented 2 years ago

Hi folks,

An interesting crash was found while fuzz testing of the faad binary which can be triggered via a malformed AAC file. Although this malformed file only crashes the program as-is, it could potentially be crafted further and create a security issue where these kinds of files would be able compromise the process's memory through taking advantage of affordances given by memory corruption. It's recommend to harden the code to prevent these kinds of bugs as it could greatly mitigate such this issue and even future bugs.

Download the repro file (~1.3mb): https://ufile.io/bhp0iun8

debug log

$ gdb -q faad
Reading symbols from faad...

(gdb) set environment LD_PRELOAD=/usr/lib/libefence.so

(gdb) r -o test.wav crash.aac
Starting program: faad -o /tmp/test.wav crash.aac

  Electric Fence 2.2 Copyright (C) 1987-1999 Bruce Perens <bruce@perens.com>
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
 *********** Ahead Software MPEG-4 AAC Decoder V2.7 ******************

 Patched for Squeezebox Server:
 * ALAC decoder integrated
 * Seeking support with -j and -e switches
 * STDIN support
 * utgg win32 STDOUT patch
 * Source at https://github.com/ralph-irving/faad2

 Copyright 2002-2004: Ahead Software AG
 http://www.audiocoding.com
 Floating point version

 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License.

 **************************************************************************

  Electric Fence 2.2 Copyright (C) 1987-1999 Bruce Perens <bruce@perens.com>
file info:

LC AAC  35.492 secs, 2 ch, 44100 Hz

Warning: Channel coupling not yet implemented
Warning: Bitstream value not allowed by specification

  ---------------------
 | Config:  2 Ch       |
  ---------------------
 | Ch |    Position    |
  ---------------------
 | 00 | Left front     |
 | 01 | Right front    |
  ---------------------

Warning: Gain control not yet implemented
Warning: Maximum number of bitstream elements exceeded
Warning: Maximum number of bitstream elements exceeded
Warning: Bitstream value not allowed by specification
Warning: Maximum number of bitstream elements exceeded
Warning: Maximum number of bitstream elements exceeded
Warning: Maximum number of bitstream elements exceeded
Warning: Unexpected channel configuration change
Warning: Unexpected channel configuration change
Warning: Bitstream value not allowed by specification
Warning: Unexpected channel configuration change
Warning: Unexpected channel configuration change
Warning: Channel coupling not yet implemented
Warning: Bitstream value not allowed by specification
Warning: Bitstream value not allowed by specification
Warning: Bitstream value not allowed by specification
Warning: Bitstream value not allowed by specification
Warning: Unexpected channel configuration change
Warning: Bitstream value not allowed by specification
Warning: Bitstream value not allowed by specification
Warning: Bitstream value not allowed by specification
Warning: Unexpected channel configuration change
Warning: Maximum number of bitstream elements exceeded
Warning: Maximum number of bitstream elements exceeded
Warning: Maximum number of bitstream elements exceeded
Warning: Maximum number of bitstream elements exceeded
Warning: Maximum number of bitstream elements exceeded
Warning: Maximum number of bitstream elements exceeded
Warning: PCE shall be the first element in a frame
Warning: Unexpected channel configuration change
Warning: Bitstream value not allowed by specification
Warning: Invalid number of channels
Warning: Invalid number of channels
...

ElectricFence Exiting: mmap() failed: 
Program received signal SIGSEGV, Segmentation fault.
__strlen_avx2 () at ../sysdeps/x86_64/multiarch/strlen-avx2.S:65

(gdb) bt
#0  __strlen_avx2 () at ../sysdeps/x86_64/multiarch/strlen-avx2.S:65
#1  0x00007ffff7dc462f in EF_Printv () from /usr/lib/libefence.so
#2  0x00007ffff7dc4845 in EF_Exitv () from /usr/lib/libefence.so
#3  0x00007ffff7dc48f9 in EF_Exit () from /usr/lib/libefence.so
#4  0x00007ffff7dc4226 in Page_Create () from /usr/lib/libefence.so
#5  0x00007ffff7dc380c in ?? () from /usr/lib/libefence.so
#6  0x00007ffff7dc3e7e in memalign () from /usr/lib/libefence.so
#7  0x000055555557c59f in mp4ff_read_sample (f=0x7ffff793dfa8, track=0, sample=569, audio_buffer=0x7ffffffe2118, bytes=0x7ffffffe210c) at mp4ff.c:453
#8  0x000055555555943d in decodeMP4fileAAC (seek_end=<optimized out>, seek_to=<optimized out>, song_length=<synthetic pointer>, adts_out=0, infoOnly=0, noGapless=0, downMatrix=<optimized out>, 
    fileType=1, outputFormat=1, to_stdout=0, adts_fn=0x7ffffffe42c0 "", sndfile=0x7ffffffe32b0 "/tmp/test.wav", infile=0x7ffff793dfa8) at main.c:965
#9  main (argc=<optimized out>, argv=<optimized out>) at main.c:1595

(gdb) i r
rax            0x7ffffffe1ea8      140737488232104
rbx            0x0                 0
rcx            0x0                 0
rdx            0x0                 0
rsi            0x73                115
rdi            0x0                 0
rbp            0x7ffffffe1e16      0x7ffffffe1e16
rsp            0x7ffffffe1e08      0x7ffffffe1e08
r8             0x7ffff7c4a660      140737350248032
r9             0x0                 0
r10            0x7ffff7dc2a50      140737351789136
r11            0x7ffff7be8660      140737349846624
r12            0x7ffffffe1e17      140737488231959
r13            0x7ffff7dc4c60      140737351797856
r14            0x7ffffffe1e80      140737488232064
r15            0x7ffff7dc4bc0      140737351797696
rip            0x7ffff7be8675      0x7ffff7be8675 <__strlen_avx2+21>
eflags         0x10283             [ CF SF IF RF ]
cs             0x33                51
ss             0x2b                43
ds             0x0                 0
es             0x0                 0
fs             0x0                 0
gs             0x0                 0

(gdb) x/i $rip
=> 0x7ffff7be8675 <__strlen_avx2+21>:   vpcmpeqb (%rdi),%ymm0,%ymm1

(gdb) exploitable
Description: Access violation
Short description: AccessViolation (21/22)
Hash: c462e0259d99ca6f6f03acfb38e184b9.f54d04adfecdb4d38a0b67dd4ed1dec0
Exploitability Classification: UNKNOWN
Explanation: The target crashed due to an access violation but there is not enough additional information available to determine exploitability.
mherger commented 2 years ago

Hi @retpoline - thanks for this report! Is this an issue you're only seeing with our modified version of faad, or is this something we inherited from upstream? Or which has been fixed upstreams already?

Please attach the test file to this report.

ralph-irving commented 2 years ago

Fixed. Thanks for reporting the issue.

(gdb) run -o nocrash.wav crash.m4a
Starting program: faad -o nocrash.wav crash.m4a
 *********** Ahead Software MPEG-4 AAC Decoder V2.7 ******************

 Patched for Squeezebox Server:
 * ALAC decoder integrated
 * Seeking support with -j and -e switches
 * STDIN support
 * utgg win32 STDOUT patch
 * Source at https://github.com/ralph-irving/faad2

 Build: Feb  5 2022
 Copyright 2002-2004: Ahead Software AG
 http://www.audiocoding.com
 Floating point version

 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License.

 **************************************************************************

file info:

LC AAC  35.492 secs, 2 ch, 44100 Hz

Error decoding file.
[Inferior 1 (process 20540) exited normally]
retpoline commented 2 years ago

Hi @retpoline - thanks for this report! Is this an issue you're only seeing with our modified version of faad, or is this something we inherited from upstream? Or which has been fixed upstreams already?

Please attach the test file to this report.

Should affect both. See the ufilo.io link for the repro, but it looks like the issue has been fixed now.

michaelherger commented 2 years ago

Thanks, both of you!