lame: stack-based buffer overflow in III_i_stereo (layer3.c)

Description:
lame is a high quality MPEG Audio Layer III (MP3) encoder licensed under the LGPL.

Few notes before the details of this bug. Time ago a fuzz was done by Brian Carpenter and Jakub Wilk which posted the results on the debian bugtracker. In cases like this, when upstream is not active and people do not post on the upstream bugzilla is easy discover duplicates, so I downloaded all available testcases, and noone of the bug you will see on my blog is a duplicate of an existing issue. Upstream seems a bit dead, latest release was into 2011, so this blog post will probably forwarded on the upstream bugtracker just for the record.

The complete ASan output of the issue:

# lame -f -V 9 $FILE out.wav
==30141==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7ffd587a7600 at pc 0x7f95cdaf0f34 bp 0x7ffd587a6250 sp 0x7ffd587a6248
WRITE of size 4 at 0x7ffd587a7600 thread T0
    #0 0x7f95cdaf0f33 in III_i_stereo /var/tmp/portage/media-sound/lame-3.99.5-r1/work/lame-3.99.5/mpglib/layer3.c:1236:28
    #1 0x7f95cdaf0f33 in decode_layer3_frame /var/tmp/portage/media-sound/lame-3.99.5-r1/work/lame-3.99.5/mpglib/layer3.c:1753
    #2 0x7f95cdaaa3ca in decodeMP3_clipchoice /var/tmp/portage/media-sound/lame-3.99.5-r1/work/lame-3.99.5/mpglib/interface.c:615:13
    #3 0x7f95cdaa7c13 in decodeMP3 /var/tmp/portage/media-sound/lame-3.99.5-r1/work/lame-3.99.5/mpglib/interface.c:696:12
    #4 0x7f95cda68092 in decode1_headersB_clipchoice /var/tmp/portage/media-sound/lame-3.99.5-r1/work/lame-3.99.5/libmp3lame/mpglib_interface.c:149:11
    #5 0x7f95cda6d94a in hip_decode1_headersB /var/tmp/portage/media-sound/lame-3.99.5-r1/work/lame-3.99.5/libmp3lame/mpglib_interface.c:436:16
    #6 0x7f95cda6d94a in hip_decode1_headers /var/tmp/portage/media-sound/lame-3.99.5-r1/work/lame-3.99.5/libmp3lame/mpglib_interface.c:379
    #7 0x51efa6 in lame_decode_fromfile /var/tmp/portage/media-sound/lame-3.99.5-r1/work/lame-3.99.5/frontend/get_audio.c:2099:19
    #8 0x51efa6 in read_samples_mp3 /var/tmp/portage/media-sound/lame-3.99.5-r1/work/lame-3.99.5/frontend/get_audio.c:877
    #9 0x51efa6 in get_audio_common /var/tmp/portage/media-sound/lame-3.99.5-r1/work/lame-3.99.5/frontend/get_audio.c:785
    #10 0x51e4fa in get_audio /var/tmp/portage/media-sound/lame-3.99.5-r1/work/lame-3.99.5/frontend/get_audio.c:688:16
    #11 0x50f776 in lame_encoder_loop /var/tmp/portage/media-sound/lame-3.99.5-r1/work/lame-3.99.5/frontend/lame_main.c:456:17
    #12 0x50f776 in lame_encoder /var/tmp/portage/media-sound/lame-3.99.5-r1/work/lame-3.99.5/frontend/lame_main.c:531
    #13 0x50c43f in lame_main /var/tmp/portage/media-sound/lame-3.99.5-r1/work/lame-3.99.5/frontend/lame_main.c:707:15
    #14 0x510793 in c_main /var/tmp/portage/media-sound/lame-3.99.5-r1/work/lame-3.99.5/frontend/main.c:470:15
    #15 0x510793 in main /var/tmp/portage/media-sound/lame-3.99.5-r1/work/lame-3.99.5/frontend/main.c:438
    #16 0x7f95cc660680 in __libc_start_main /tmp/portage/sys-libs/glibc-2.23-r3/work/glibc-2.23/csu/../csu/libc-start.c:289
    #17 0x41c998 in _init (/usr/bin/lame+0x41c998)

Address 0x7ffd587a7600 is located in stack of thread T0 at offset 5024 in frame
    #0 0x7f95cdadc48f in decode_layer3_frame /var/tmp/portage/media-sound/lame-3.99.5-r1/work/lame-3.99.5/mpglib/layer3.c:1659

  This frame has 4 object(s):
    [32, 344) 'scalefacs'
    [416, 5024) 'hybridIn' 0x10002b0ecec0:[f2]f2 f2 f2 f2 f2 f2 f2 f2 f2 f2 f2 f2 f2 f2 f2
  0x10002b0eced0: f2 f2 f2 f2 f2 f2 f2 f2 f2 f2 f2 f2 f2 f2 f2 f2
  0x10002b0ecee0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x10002b0ecef0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x10002b0ecf00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x10002b0ecf10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
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
==30141==ABORTING

Affected version:
3.99.5

Fixed version:
N/A

Commit fix:
N/A

Credit:
This bug was discovered by Agostino Sarubbo of Gentoo.

CVE:
CVE-2017-9871

Reproducer:
https://github.com/asarubbo/poc/blob/master/00293-lame-stackoverflow-III_i_stereo

Timeline:
2017-06-01: bug discovered
2017-06-17: blog post about the issue
2017-06-25: CVE assigned

Note:
This bug was found with American Fuzzy Lop.

Permalink:

lame: stack-based buffer overflow in III_i_stereo (layer3.c)

This entry was posted in advisories, security. Bookmark the permalink.

6 Responses to lame: stack-based buffer overflow in III_i_stereo (layer3.c)

  1. Hugo Lefeuvre says:

    Hi,

    I can’t reproduce this issue on my system. asan doesn’t report anything and I get “Warning: Unsupported audio format” (same for CVE-2017-9869/70/72).

    How did you build lame ?

    Reply
  2. Hugo Lefeuvre says:

    I have tried to re-build libsndfile with protections disabled, but it didn’t help.

    Also, I have noticed that asan reports memory leaks under gdb (otherwise not).

    The leaks are identical for all reproducers (290/291/293/294):

    (gdb) r -V 9 ~/Downloads/00290-lame-globaloverflow-II_step_one out.wav
    Starting program: /usr/local/bin/lame -V 9 ~/Downloads/00290-lame-globaloverflow-II_step_one out.wav
    [Thread debugging using libthread_db enabled]
    Using host libthread_db library “/lib/x86_64-linux-gnu/libthread_db.so.1”.

    =================================================================
    ==15502==ERROR: LeakSanitizer: detected memory leaks

    Direct leak of 336 byte(s) in 1 object(s) allocated from:
    #0 0x7ffff6effed0 in calloc (/usr/lib/x86_64-linux-gnu/libasan.so.3+0xc1ed0)
    #1 0x55555559f119 in lame_init /home/user/Development/lame/lame-3.99.5+repack1/libmp3lame/lame.c:2426

    Indirect leak of 88584 byte(s) in 1 object(s) allocated from:
    #0 0x7ffff6effed0 in calloc (/usr/lib/x86_64-linux-gnu/libasan.so.3+0xc1ed0)
    #1 0x55555559f16b in lame_init_old /home/user/Development/lame/lame-3.99.5+repack1/libmp3lame/lame.c:2314
    #2 0x55555559f16b in lame_init /home/user/Development/lame/lame-3.99.5+repack1/libmp3lame/lame.c:2430

    Indirect leak of 64 byte(s) in 1 object(s) allocated from:
    #0 0x7ffff6effed0 in calloc (/usr/lib/x86_64-linux-gnu/libasan.so.3+0xc1ed0)
    #1 0x55555558ecc6 in id3v2_add_latin1 /home/user/Development/lame/lame-3.99.5+repack1/libmp3lame/id3tag.c:877

    Indirect leak of 48 byte(s) in 1 object(s) allocated from:
    #0 0x7ffff6effed0 in calloc (/usr/lib/x86_64-linux-gnu/libasan.so.3+0xc1ed0)
    #1 0x55555558e53d in local_strdup /home/user/Development/lame/lame-3.99.5+repack1/libmp3lame/id3tag.c:391
    #2 0x7372657620737468 ()

    Reply
  3. Hugo Lefeuvre says:

    Hi ago,

    I have tried with various versions of clang on different systems and got different results, but not the excepted one. When I try with clang 3.8 in stretch, I also get these memory leaks, but with clang 4.0 in experimental, asan doesn’t report anything anymore.

    There is probably something special with the linked libraries from the Debian repositories, but I think I’m going to stop here because I cannot spend so much time on these issues.

    For the record, I have reported these issues to upstream’s bug tracker and they consider them to be duplicates of already-found & fixed issues (e.g. https://sourceforge.net/p/lame/bugs/483/).

    Reply
    • ago says:

      You maybe will found the bug by fuzzing (on a debian system) the debian version of lame. Feel free to ask to Jakub Wilk or Henri Salo, afaik they have a working fuzz environment on debian.

      Reply

Leave a Reply

Your email address will not be published. Required fields are marked *