Menu

#240 Title: SIGSEGV in mpg123 v1.23.7

1.23.x
closed-fixed
None
5
2016-11-05
2016-09-26
Jerold H.
No
Summary: Segfault (unsigned long underflow) in mpg123 when parsing malformed ID3 header size in id3.c:755:765.
Discovered by : Han Lee & Jerold Hoong

- beep.mp3 id3 header  : 4944 3303 0000 0000 0026 
- crash.mp3 id3 header : 4944 3303 0040 0000 0006

----------------------------
RUN with legit beep.mp3 file
----------------------------

Breakpoint 1, INT123_parse_new_id3 (fr=fr@entry=0x7421b0, first4bytes=<optimized out>) at src/libmpg123/id3.c:755
755                     while(tagpos < length-10) /* I want to read at least a full header */
(gdb) print tagpos
$1 = 0
(gdb) print length
$2 = 38
(gdb) print length-10
$3 = 28
(gdb)

----------------------------
RUN with malformed crash.mp3
----------------------------

Breakpoint 1, INT123_parse_new_id3 (fr=fr@entry=0x7421c0, first4bytes=<optimized out>) at src/libmpg123/id3.c:755
755                     while(tagpos < length-10) /* I want to read at least a full header */
(gdb) print tagpos
$1 = 1414546737
(gdb) print length
$2 = 6
(gdb) print length-10
$3 = 18446744073709551612
(gdb) n
Breakpoint 2, INT123_parse_new_id3 (fr=fr@entry=0x7421b0, first4bytes=<optimized out>) at src/libmpg123/id3.c:765
765                         if( !( ((tagdata[tagpos+i] > 47) && (tagdata[tagpos+i] < 58))
(gdb) n
759                         int head_part = fr->id3v2.version == 2 ? 3 : 4; /* bytes of frame title and of framesize value */
(gdb) n
765                         if( !( ((tagdata[tagpos+i] > 47) && (tagdata[tagpos+i] < 58))
(gdb) n

Program received signal SIGSEGV, Segmentation fault.
INT123_parse_new_id3 (fr=fr@entry=0x7421b0, first4bytes=<optimized out>) at src/libmpg123/id3.c:765
765                         if( !( ((tagdata[tagpos+i] > 47) && (tagdata[tagpos+i] < 58))
(gdb) bt
#0  INT123_parse_new_id3 (fr=fr@entry=0x7421b0, first4bytes=<optimized out>) at src/libmpg123/id3.c:765
#1  0x0000000000448ac3 in handle_id3v2 (newhead=<optimized out>, fr=0x7421b0) at src/libmpg123/parse.c:1071
#2  wetwork (newheadp=<optimized out>, fr=<optimized out>) at src/libmpg123/parse.c:1241
#3  INT123_read_frame (fr=fr@entry=0x7421b0) at src/libmpg123/parse.c:536
#4  0x0000000000493862 in get_next_frame (mh=0x7421b0) at src/libmpg123/libmpg123.c:623
#5  mpg123_decode_frame (mh=0x7421b0, num=num@entry=0x741968 <framenum>, audio=audio@entry=0x7fffffffe2e0, bytes=bytes@entry=0x7fffffffe2e8) at src/libmpg123/libmpg123.c:859
#6  0x000000000042ecc8 in play_frame () at src/mpg123.c:763
#7  0x0000000000406735 in main (sys_argc=<optimized out>, sys_argv=<optimized out>) at src/mpg123.c:1369
(gdb)

--------
Analysis
--------

Description: Access violation on source operand
Short description: SourceAv (19/22)
Hash: 6bd52e79e6017b9e236d4d9edea21a67.d278ec4c10e616aa909c08fc399072bd
Exploitability Classification: UNKNOWN
Explanation: The target crashed on an access violation at an address matching the source operand of the current instruction. This likely indicates a read access violation.
Other tags: AccessViolation (21/22)
4 Attachments

Discussion

  • Thomas Orgis

    Thomas Orgis - 2016-09-26

    Oh dear … thanks for that detailed report. What a usual blunder that
    was there from the beginning of ID3v2 parsing support in mpg123.

    I prepared a release tarball with a verbose fix:

    http://mpg123.org/download/mpg123-1.23.8.tar.bz2
    

    Would you please verify that it fixes this? Also, I will put this into
    the announcement for a hotfix for any affected mpg123 release:

    perl -pi -e 's:(while\()(tagpos < length-10\)):${1}length >= 10 && $2:' $(find src -name id3.c)
    

    Can you confirm that it works, too? Just pick any random version since
    0.60. I tested it with 0.60 and 1.12.2 . I want to give this quick fix
    to distros shipping older versions than 1.23.x .

     
  • Jerold H.

    Jerold H. - 2016-09-27

    Looks like the length check fix in id3.c:726 is sufficient. Here is the output I get:

    root@fizza:~/src/mpg123-1.23.8# ./src/mpg123 -w /dev/null /home/v00d00sec/Desktop/mpg123_crashfiles/crash.mp3
    High Performance MPEG 1.0/2.0/2.5 Audio Player for Layers 1, 2 and 3
        version 1.23.8; written and copyright by Michael Hipp and others
        free software (LGPL) without any warranty but with best wishes
    
    Directory: /home/v00d00sec/Desktop/mpg123_crashfiles/
    
    Terminal control enabled, press 'h' for listing of keys and functions.
    
    Playing MPEG stream 1 of 1: crash.mp3 ...
    [src/libmpg123/id3.c:729] warning: ID3v2: unrealistic small tag lengh 6, skipping
    
    MPEG 1.0 L III cbr128 44100 mono
    
    [0:00] Decoding of crash.mp3 finished.
    root@fizza:~/src/mpg123-1.23.8# 
    

    I have also tested the perl one-liner fix on versions 1.0.0, 1.4.3 and 1.11.0. It worked without any issues.

     
  • Thomas Orgis

    Thomas Orgis - 2016-09-27

    Thank you very much … announcing the release now.

     
  • Thomas Orgis

    Thomas Orgis - 2016-11-05
    • status: open --> closed-fixed
     

Log in to post a comment.