lewdlime / abcm2ps

abcm2ps is a command line program which converts ABC to music sheet in PostScript or SVG format. It is an extension of abc2ps which may handle many voices per staff. abcm2ps is Copyright © 2014-2016 Jean-Francois Moine.
http://moinejf.free.fr/
GNU General Public License v3.0
80 stars 31 forks source link

Divide By Zero vulnerability in function parse_len(). #68

Closed Loginsoft-Research closed 4 years ago

Loginsoft-Research commented 4 years ago

What is the vulnerability? Divide By Zero vulnerability is discovered in abcm2ps (8.14.6-master). This can be triggered by sending a crafted abc file to the abcm2ps binary.

Affected version-: 8.14.6-master

Command-: ./abcm2ps $POC

Reproducer file-: Reproducer

Synopsis-: while doing research on vulnerability in function parse_len() at abcparse.c:1822. Variable fac is not being checked before performing division with variable len. Due to this availability of the application is affected.

Vulnerable code-:

        // len=0x300, fac=0x0
if (len % fac)
    syntax("Bad length divisor", p - 1);
len /= fac;
*p_len = len;
return p;

Debug-:

GDB-:

Program received signal SIGFPE, Arithmetic exception.
[ Legend: Modified register | Code | Heap | Stack | String ]
──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── registers ────
$rax   : 0x300             
$rbx   : 0x0               
$rcx   : 0x0               
$rdx   : 0x0               
$rsp   : 0x00007fffffffe0d0  →  0x00007fffffffe134  →  0x000001220000000f  →  0x0000000000000000
$rbp   : 0x00007fffffffe100  →  0x00007fffffffe160  →  0x00007fffffffe230  →  0x00007fffffffe260  →  0x00007fffffffe280  →  0x00007fffffffe2f0  →  0x00007fffffffe330  →  0x00007fffffffe3b0
$rsi   : 0x0000625000000124  →  "4////////////////////////////////D4]|zD EF- FED2|D[...]"
$rdi   : 0x00007fffffffe098  →  0x00007ffff6f42e80  →  0x73006c6f74727473 ("strtol"?)
$rip   : 0x000055555556197c  →  <parse_len+298> idiv DWORD PTR [rbp-0x8]
$r8    : 0xa               
$r9    : 0x0               
$r10   : 0x1               
$r11   : 0xa               
$r12   : 0x000055555555b1b0  →  <_start+0> xor ebp, ebp
$r13   : 0x00007fffffffe500  →  0x0000000000000002
$r14   : 0x0               
$r15   : 0x0               
$eflags: [zero carry parity ADJUST sign trap INTERRUPT direction overflow RESUME virtualx86 identification]
$cs: 0x0033 $ss: 0x002b $ds: 0x0000 $es: 0x0000 $fs: 0x0000 $gs: 0x0000 
──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── stack ────
0x00007fffffffe0d0│+0x0000: 0x00007fffffffe134  →  0x000001220000000f  →  0x0000000000000000     ← $rsp
0x00007fffffffe0d8│+0x0008: 0x00007fffffffe130  →  0x0000000f000000c0  →  0x0000000000000000
0x00007fffffffe0e0│+0x0010: 0x000000c0557cf260  →  0x0000000000000000
0x00007fffffffe0e8│+0x0018: 0x0000625000000145  →  "D4]|zD EF- FED2|D8|"
0x00007fffffffe0f0│+0x0020: 0x0000625000000125  →  "////////////////////////////////D4]|zD EF- FED2|D8[...]"
0x00007fffffffe0f8│+0x0028: 0x0000030000000000  →  0x0000000000000000
0x00007fffffffe100│+0x0030: 0x00007fffffffe160  →  0x00007fffffffe230  →  0x00007fffffffe260  →  0x00007fffffffe280  →  0x00007fffffffe2f0  →  0x00007fffffffe330  →  0x00007fffffffe3b0     ← $rbp
0x00007fffffffe108│+0x0038: 0x0000555555563343  →  <parse_note+1133> mov QWORD PTR [rbp-0x48], rax
────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── code:x86:64 ────
   0x555555561972 <parse_len+288>  je     0x5555555618e9 <parse_len+151>
   0x555555561978 <parse_len+294>  mov    eax, DWORD PTR [rbp-0x4]
   0x55555556197b <parse_len+297>  cdq    
 → 0x55555556197c <parse_len+298>  idiv   DWORD PTR [rbp-0x8]
   0x55555556197f <parse_len+301>  mov    eax, edx
   0x555555561981 <parse_len+303>  test   eax, eax
   0x555555561983 <parse_len+305>  je     0x55555556199c <parse_len+330>
   0x555555561985 <parse_len+307>  mov    rax, QWORD PTR [rbp-0x18]
   0x555555561989 <parse_len+311>  sub    rax, 0x1
─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── source:abcparse.c+1822 ────
   1817             p = q;
   1818         } else {
   1819             fac *= 2;
   1820         }
   1821     }
          // len=0x300, fac=0x0
 → 1822     if (len % fac)
   1823         syntax("Bad length divisor", p - 1);
   1824     len /= fac;
   1825     *p_len = len;
   1826     return p;
   1827  }
────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── threads ────
[#0] Id 1, Name: "abcm2ps", stopped, reason: SIGFPE
──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── trace ────
[#0] 0x55555556197c → parse_len(p=0x625000000145 "D4]|zD EF- FED2|D8|", dur_u=0xc0, p_len=0x7fffffffe130)
[#1] 0x555555563343 → parse_note(p=0x625000000124 "4", '/' <repeats 32 times>, "D4]|zD EF- FED2|D8|", flags=0x4)
[#2] 0x555555562504 → parse_line(p=0x625000000122 "B,4", '/' <repeats 32 times>, "D4]|zD EF- FED2|D8|")
[#3] 0x55555555d51f → abc_parse(p=0x625000000100 "[C8E8]|zE FG- GEC2|[B,3E3][B,D]- [B,4", '/' <repeats 32 times>, "D4]|zD EF- FED2|D8|", fname=0x606000000a40 "result/crashes/id:000037,sig:08,src:000033,op:havoc,rep:16", ln=0x11)
[#4] 0x5555555826c0 → txt_add_eos(fname=0x606000000a40 "result/crashes/id:000037,sig:08,src:000033,op:havoc,rep:16", linenum=0x11)
[#5] 0x5555555839c3 → frontend(s=0x61f000000141 "[C8E8]|zE FG- GEC2|[B,3E3][B,D]- [B,4", '/' <repeats 32 times>, "D4]|zD EF- FED2|D8|\nV:LH\n[C,3G,3][C,G,]- [C,4G,4]|[C,3G,3][C,G,]- [C,4G,4]|[B,,3G,3][B,,G,]- [B,,4G,4]|\\\n[B,,3G,3][B,,G,]- [B,,4G,4]|[_B,,3F,3][B,,F,]- [B,,4F,4]|\n\nX:2\nT:8th Sonata for piano\nC:L. van Beethoven\nM:C\nL:1/16\nQ:1/8=66\n%%staves {1 2}\nK:Cm\n% .. even\031when there are a lot of notes\nV:1\n!fp![E,4G,4C4]- [E,3/G,3/C3/]!3![G,/C/]!4![G,3/=B,3/D3/]!5![G,/C/E/] ([=A, (T B)]\nK:A\n% Breton words on a4C4E4]!4![=B,2D2])z2|\\\n!fp!!3![=B,4D4F4]- [B,3/D3/F3/=[B,/D/F/][B,3/D3/G3/][B,/D/A/] ([B,4D4A4]!3![C2E2G2])z2|\nV:2\n[C,,4E,,4G,,4C,4]- [C,,3/E,,3/G,,3/C,3/]!2!E,/!3!D,3/!4!C,/ (!2!^F,4G,2)z _A,,|\\\n_A,4-A,3/!2!A,/!1!G,3/=F,/ E,4-E,2z3/ E,/|\n\nX:3\nT: Praeludium II (WT II)\nC: J.S.dBach\nM\035 C\nL: 1/16\nQ:1/4=66\n%%staves {RH LH}\n%%MIDI program 6\nK:Cm\n% same as bach.abc (abc2ps-1.3.0) but rewritten in a more standard way\nV:RH\n  zGFG AFEF GEDE FDCD     | E2c2F2c2 E2c2D2=B2", ' ' <repeats 18 times>, "| \nV:LH\n  C,2C2F,2C2 E,2C2D,2=B,2 | C,G,F,G, A,F,E,F, G,E,D,E, F,D,C,D, |  \n\nX:4\nT:Allegro grazioso\nC:Schumann\nM:C\nL:1/8\nQ:1/4=66\n%%staves {1 (2 3)}\nK:G\nV:1\n(!p!B2AB G3)(A |Bcd[Ge]) ([F3A3][^GB])|([A2c2][^GB][Ac] AF=GA)|[G2B2][F2A2] {/G}G3B|\nV:2\n% this voice is not complete, but the measure must be respected\n G,2C2 xD3-    |D2x2\t x4\t      | A,2D2\t\tC2x2  |x8\t\t   |\nV:2\357(G,DCD B,D2)(F,|G,A,B,C  (D2)CB,)     |(A,EDE\t\tCDB,C)|D2[D,2C2]  [G,3B,3]D|\n\n% --- vocal ---\n\nX:5\nT:Tridal a ra va c'halon\nT:(Mor Fawr Wyt Ti!)\nM:4/4\nL:1/8\nQ:1/4=48\n%%staves [(S\025A) (T B)]\nK:A\n% Breton words on a Wales ahoral\nV:S\nEEE\t  |C3E\t   EEFF        |(D2F3)\t  FFF\t |E3C   EEDD\t\t |C4   z:|\nw:Ka-na a |rin, ka-na a rin be-|pred,* rag an Ao-|trou en-eus va zan-tel-|let.\nw:Eñ eo va|nerz, eñ eo i-vez va|Zad,*    eñ eo va|han, ka-na a rin e     |hloar.\nV:A\nCCC\t  |A,3A,   B,CA,A,     |(B,2A,3)  DDB,   |C3A,  B,A,A,G,\t |A,4  z:|\nV:T\nA,A,A,\t  |E,3E,   G,A,F,F,    |(F,2F,3)  A,A,G, |A,3A, G,A,F,E,\t |E,4  z:|\nV:B\nA,,A,,A,, |A,,3C,  B,,A,,D,D,  |(B,,2D,3) D,D,B,,|E,3F, E,C,B,,E,,\t |A,,4 z:|\n\n% organ ---\n\nX:6\nT:Wär Gott nicht mit uns diese Zeit\nC:Johann Nicolaus Hanff\nM:C\nL:1/8\nQ:1/4=66\n%%staves [1 (2 3) 4]\nV:1 nm=\"Rückpos\"\nV:2 nm=\"Orvano\"\nK:Am\nV:1\n%%MIDI program 53\nA3B    c2c2    |d2e2    de/f/P ^c3/d/|d8    |z8\t\t  |\nV:2\n%%MIDI program 73\nz2E2-  E2AG    |F2E2    F2E2\t     |F6  F2|E2CD  ,E3F/G/|\nV:3\n%%MIDI program 73\nz2C2-  CB,A,2  |A,8\t\t     |A,6 D2|C2A,B, C3D/E/|\nV:4\n%%MIDI program 73\nz2A,2- A,G,F,E,|D,2^C,2 D,2A,,2      |D,,8  |z4\t    z2A,2 |\n\nX:7\nT:Qui Toli\213 (Trio)\nC:André Raison\nM:3/4\nL:1/\020", ftype=0x0, fname=0x606000000a40 "result/crashes/id:000037,sig:08,src:000033,op:havoc,rep:16", linenum=0x11)
[#6] 0x55555555b933 → treat_file(fn=0x7fffffffe78a "result/crashes/id:000037,sig:08,src:000033,op:havoc,rep:16", ext=0x5555555b4126 "abc")
[#7] 0x55555555ba1f → treat_abc_file(fn=0x7fffffffe78a "result/crashes/id:000037,sig:08,src:000033,op:havoc,rep:16")
[#8] 0x55555555d010 → main(argc=0x0, argv=0x7fffffffe510)
───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
0x000055555556197c in parse_len (p=0x625000000145 "D4]|zD EF- FED2|D8|", dur_u=0xc0, p_len=0x7fffffffe130) at abcparse.c:1822
1822        if (len % fac)
gef➤  p fac
$2 = 0x0
gef➤  i r
rax            0x300    0x300
rbx            0x0  0x0
rcx            0x0  0x0
rdx            0x0  0x0
rsi            0x625000000124   0x625000000124
rdi            0x7fffffffe098   0x7fffffffe098
rbp            0x7fffffffe100   0x7fffffffe100
rsp            0x7fffffffe0d0   0x7fffffffe0d0
r8             0xa  0xa
r9             0x0  0x0
r10            0x1  0x1
r11            0xa  0xa
r12            0x55555555b1b0   0x55555555b1b0
r13            0x7fffffffe500   0x7fffffffe500
r14            0x0  0x0
r15            0x0  0x0
rip            0x55555556197c   0x55555556197c <parse_len+298>
eflags         0x10212  [ AF IF RF ]
cs             0x33 0x33
ss             0x2b 0x2b
ds             0x0  0x0
es             0x0  0x0
fs             0x0  0x0
gs             0x0  0x0

Asan-:

ASAN:DEADLYSIGNAL
=================================================================
==24156==ERROR: AddressSanitizer: FPE on unknown address 0x56497236697c (pc 0x56497236697c bp 0x7ffc55450da0 sp 0x7ffc55450d70 T0)
    #0 0x56497236697b in parse_len /home/farid/Desktop/fuzzing/abcm2ps/abcparse.c:1822
    #1 0x564972368342 in parse_note /home/farid/Desktop/fuzzing/abcm2ps/abcparse.c:2411
    #2 0x564972367503 in parse_line /home/farid/Desktop/fuzzing/abcm2ps/abcparse.c:2066
    #3 0x56497236251e in abc_parse /home/farid/Desktop/fuzzing/abcm2ps/abcparse.c:166
    #4 0x5649723876bf in txt_add_eos /home/farid/Desktop/fuzzing/abcm2ps/front.c:379
    #5 0x5649723889c2 in frontend /home/farid/Desktop/fuzzing/abcm2ps/front.c:891
    #6 0x564972360932 in treat_file /home/farid/Desktop/fuzzing/abcm2ps/abcm2ps.c:240
    #7 0x564972360a1e in treat_abc_file /home/farid/Desktop/fuzzing/abcm2ps/abcm2ps.c:283
    #8 0x56497236200f in main /home/farid/Desktop/fuzzing/abcm2ps/abcm2ps.c:1041
    #9 0x7f45c9e15b96 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21b96)
    #10 0x5649723601d9 in _start (/home/farid/Desktop/fuzzing/abcm2ps/abcm2ps+0x71d9)

AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: FPE /home/farid/Desktop/fuzzing/abcm2ps/abcparse.c:1822 in parse_len
==24156==ABORTING
hkiel commented 4 years ago

I can confirm the fix. This can be closed.

moinejf commented 4 years ago

ok