================
Author : qflb.wu
===============


Introduction:
=============
https://www.linuxsampler.org/libgig/
libgig is a C++ library for loading, modifying existing and creating new Gigasampler (.gig) files and DLS (Downloadable Sounds) Level 1/2 files, KORG sample based instruments (.KSF and .KMP files), SoundFont v2 (.sf2) files and AKAI sampler data.


Affected version:
=====
4.0.0


Vulnerability Description:
==========================
1.
the gig::Region::Region function in gig.cpp in libgig 4.0.0 can cause a denial of service(Null pointer dereference and application crash) via a crafted gig file.


./gigdump libgig_4.0.0_null_pointer_dereference_1.gig


----debug info:----
Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7bc07df in gig::Region::Region (this=0x614ce0,
    pInstrument=<optimized out>, rgnList=0x610230) at gig.cpp:2970
2970                    if (file->pWavePoolTable) pDimensionRegions[i]->pSample = GetSampleFromWavePool(wavepoolindex);
(gdb) bt
#0  0x00007ffff7bc07df in gig::Region::Region (this=0x614ce0,
    pInstrument=<optimized out>, rgnList=0x610230) at gig.cpp:2970
#1  0x00007ffff7bc0b36 in gig::Instrument::Instrument (this=0x60ef80,
    pFile=<optimized out>, insList=0x60eea0, pProgress=0x7fffffffdda0)
    at gig.cpp:4404
#2  0x00007ffff7bc103e in gig::File::LoadInstruments (this=0x609160,
    pProgress=0x0) at gig.cpp:5576
#3  0x00007ffff7bbade6 in gig::File::GetFirstInstrument (
    this=this@entry=0x609160) at gig.cpp:5378
#4  0x000000000040533b in PrintInstruments (gig=gig@entry=0x609160)
    at gigdump.cpp:205
#5  0x0000000000401f34 in main (argc=<optimized out>, argv=<optimized out>)
    at gigdump.cpp:79
(gdb) disassemble 0x00007ffff7bc07ca,0x00007ffff7bc07f0
Dump of assembler code from 0x7ffff7bc07ca to 0x7ffff7bc07f0:
   0x00007ffff7bc07ca <gig::Region::Region(gig::Instrument*, RIFF::List*)+666>:je     0x7ffff7bc07e3 <gig::Region::Region(gig::Instrument*, RIFF::List*)+691>
   0x00007ffff7bc07cc <gig::Region::Region(gig::Instrument*, RIFF::List*)+668>:xor    %edx,%edx
   0x00007ffff7bc07ce <gig::Region::Region(gig::Instrument*, RIFF::List*)+670>:mov    %eax,%esi
   0x00007ffff7bc07d0 <gig::Region::Region(gig::Instrument*, RIFF::List*)+672>:mov    %rbx,%rdi
   0x00007ffff7bc07d3 <gig::Region::Region(gig::Instrument*, RIFF::List*)+675>:mov    0x138(%r13),%r14
   0x00007ffff7bc07da <gig::Region::Region(gig::Instrument*, RIFF::List*)+682>:callq  0x7ffff7b9ede0 <_ZN3gig6Region21GetSampleFromWavePoolEjPN4RIFF10progress_tE@plt>
=> 0x00007ffff7bc07df <gig::Region::Region(gig::Instrument*, RIFF::List*)+687>:mov    %rax,0x38(%r14)
   0x00007ffff7bc07e3 <gig::Region::Region(gig::Instrument*, RIFF::List*)+691>:add    $0x1,%ebp
   0x00007ffff7bc07e6 <gig::Region::Region(gig::Instrument*, RIFF::List*)+694>:add    $0x8,%r13
   0x00007ffff7bc07ea <gig::Region::Region(gig::Instrument*, RIFF::List*)+698>:cmp    %ebp,0x130(%rbx)
End of assembler dump.
(gdb) i r
rax            0x60ca906343312
rbx            0x614ce06376672
rcx            0x33
rdx            0x60a3006333184
rsi            0x00
rdi            0x6091606328672
rbp            0x00x0
rsp            0x7fffffffdcc00x7fffffffdcc0
r8             0x00
r9             0x22
r10            0x00
r11            0x246582
r12            0x6159506379856
r13            0x614ce06376672
r14            0x00
r15            0x00
rip            0x7ffff7bc07df0x7ffff7bc07df <gig::Region::Region(gig::Instrument*, RIFF::List*)+687>
eflags         0x10246[ PF ZF IF RF ]
cs             0x3351
ss             0x2b43
ds             0x00
es             0x00
---Type <return> to continue, or q <return> to quit---
fs             0x00
gs             0x00
(gdb)


ASAN:SIGSEGV
=================================================================
==40516== ERROR: AddressSanitizer: SEGV on unknown address 0x000000000038 (pc 0x7f4f87126260 sp 0x7ffd0b22ec80 bp 0x600e0000c3b0 T0)
AddressSanitizer can not provide additional info.
    #0 0x7f4f8712625f in gig::Region::Region(gig::Instrument*, RIFF::List*) /home/a/Documents/libgig-4.0.0/src/gig.cpp:2970
    #1 0x7f4f87127f4a in gig::Instrument::Instrument(gig::File*, RIFF::List*, RIFF::progress_t*) /home/a/Documents/libgig-4.0.0/src/gig.cpp:4404
    #2 0x7f4f87129fdc in gig::File::LoadInstruments(RIFF::progress_t*) /home/a/Documents/libgig-4.0.0/src/gig.cpp:5576
    #3 0x7f4f870fb6a0 in gig::File::GetFirstInstrument() /home/a/Documents/libgig-4.0.0/src/gig.cpp:5378
    #4 0x40fca6 in PrintInstruments(gig::File*) /home/a/Documents/libgig-4.0.0/src/tools/gigdump.cpp:205
    #5 0x4027aa in main /home/a/Documents/libgig-4.0.0/src/tools/gigdump.cpp:79
    #6 0x7f4f86749ec4 (/lib/x86_64-linux-gnu/libc.so.6+0x21ec4)
    #7 0x402e5c in _start (/home/a/Documents/libgig-4.0.0/src/tools/.libs/gigdump+0x402e5c)
SUMMARY: AddressSanitizer: SEGV /home/a/Documents/libgig-4.0.0/src/gig.cpp:2970 gig::Region::Region(gig::Instrument*, RIFF::List*)
==40516== ABORTING


POC:
libgig_4.0.0_null_pointer_dereference_1.gig
CVE:
CVE-2017-12950


2.
the gig::DimensionRegion::CreateVelocityTable function in gig.cpp in libgig 4.0.0 can cause a denial of service(stack buffer overflow and application crash) via a crafted gig file.


./gigdump libgig_4.0.0_stack_buffer_overflow.gig


----debug info:----
Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7bb8b44 in gig::DimensionRegion::CreateVelocityTable (
    this=<optimized out>, curveType=<optimized out>, depth=<optimized out>,
    scaling=<optimized out>) at gig.cpp:2884
2884        table[0] = 0;
(gdb) bt
#0  0x00007ffff7bb8b44 in gig::DimensionRegion::CreateVelocityTable (
    this=<optimized out>, curveType=<optimized out>, depth=<optimized out>,
    scaling=<optimized out>) at gig.cpp:2884
#1  0x00007ffff7bbf535 in gig::DimensionRegion::GetVelocityTable (
    this=<optimized out>, curveType=<optimized out>, depth=<optimized out>,
    scaling=<optimized out>) at gig.cpp:2054
#2  0x00007ffff7bbf6f3 in gig::DimensionRegion::GetCutoffVelocityTable (
    this=this@entry=0x60d3f0, vcfVelocityCurve=<optimized out>,
    vcfVelocityDynamicRange=<optimized out>, vcfVelocityScale=<optimized out>,
    vcfCutoffController=<optimized out>) at gig.cpp:2042
#3  0x00007ffff7bbffa4 in gig::DimensionRegion::DimensionRegion (
    this=0x60d3f0, pParent=<optimized out>, _3ewl=<optimized out>)
    at gig.cpp:1617
#4  0x00007ffff7bc0464 in gig::Region::LoadDimensionRegions (
    this=this@entry=0x60c3a0, rgn=rgn@entry=0x60b330) at gig.cpp:3075
#5  0x00007ffff7bc05fc in gig::Region::Region (this=0x60c3a0,
    pInstrument=<optimized out>, rgnList=0x60b330) at gig.cpp:2923
#6  0x00007ffff7bc0b36 in gig::Instrument::Instrument (this=0x60a280,
    pFile=<optimized out>, insList=0x60a1a0, pProgress=0x7fffffffdd90)
    at gig.cpp:4404
#7  0x00007ffff7bc103e in gig::File::LoadInstruments (this=0x609160,
    pProgress=0x0) at gig.cpp:5576
#8  0x00007ffff7bbade6 in gig::File::GetFirstInstrument (
---Type <return> to continue, or q <return> to quit---
    this=this@entry=0x609160) at gig.cpp:5378
#9  0x000000000040533b in PrintInstruments (gig=gig@entry=0x609160)
    at gigdump.cpp:205
#10 0x0000000000401f34 in main (argc=<optimized out>, argv=<optimized out>)
    at gigdump.cpp:79
    (gdb) disassemble
Dump of assembler code for function gig::DimensionRegion::CreateVelocityTable(gig::curve_type_t, unsigned char, unsigned char):
...
   0x00007ffff7bb8b27 <+2119>:mov    0x2e0(%rsp,%rdx,8),%rsi
   0x00007ffff7bb8b2f <+2127>:je     0x7ffff7bb8c5c <gig::DimensionRegion::CreateVelocityTable(gig::curve_type_t, unsigned char, unsigned char)+2428>
   0x00007ffff7bb8b35 <+2133>:movzbl %bpl,%ebx
   0x00007ffff7bb8b39 <+2137>:cvtsi2sd %ebx,%xmm6
   0x00007ffff7bb8b3d <+2141>:movq   $0x0,(%rax)
=> 0x00007ffff7bb8b44 <+2148>:mov    0x8(%rsi),%edi
   0x00007ffff7bb8b47 <+2151>:lea    0x8(%rax),%rcx
---Type <return> to continue, or q <return> to quit---
   0x00007ffff7bb8b4b <+2155>:mov    0xc(%rsi),%r10d
   0x00007ffff7bb8b4f <+2159>:mov    $0x1,%edx
...
(gdb) i r
rax            0x60e0506348880
rbx            0x1420
rcx            0x7ffff7669760140737344083808
rdx            0xfe254
rsi            0x2f736c6f6f742f633419195767971393379
rdi            0x22
rbp            0x00x0
rsp            0x7fffffffd8600x7fffffffd860
r8             0x60dbc06347712
r9             0x4064
r10            0x7fffffffd9f0140737488345584
r11            0x7ffff7bbf601140737349678593
r12            0x44
r13            0x60d7706346608
r14            0x60c3a06341536
r15            0x60c3a06341536
rip            0x7ffff7bb8b440x7ffff7bb8b44 <gig::DimensionRegion::CreateVelocityTable(gig::curve_type_t, unsigned char, unsigned char)+2148>
eflags         0x10246[ PF ZF IF RF ]
cs             0x3351
ss             0x2b43
ds             0x00
es             0x00
---Type <return> to continue, or q <return> to quit---
fs             0x00
gs             0x00
(gdb) x/20x $rsi+0x8
0x2f736c6f6f742f6b:Cannot access memory at address 0x2f736c6f6f742f6b
(gdb)
0x2f736c6f6f742f6f:Cannot access memory at address 0x2f736c6f6f742f6f
(gdb)


==40504== ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7ffc9ca05fa0 at pc 0x7fbea070c58b bp 0x7ffc9ca051c0 sp 0x7ffc9ca051b8
READ of size 8 at 0x7ffc9ca05fa0 thread T0
    #0 0x7fbea070c58a in gig::DimensionRegion::CreateVelocityTable(gig::curve_type_t, unsigned char, unsigned char) /home/a/Documents/libgig-4.0.0/src/gig.cpp:2881
    #1 0x7fbea0743964 in gig::DimensionRegion::GetVelocityTable(gig::curve_type_t, unsigned char, unsigned char) /home/a/Documents/libgig-4.0.0/src/gig.cpp:2054
    #2 0x7fbea0747739 in gig::DimensionRegion::DimensionRegion(gig::Region*, RIFF::List*) /home/a/Documents/libgig-4.0.0/src/gig.cpp:1617
    #3 0x7fbea074bfda in gig::Region::LoadDimensionRegions(RIFF::List*) /home/a/Documents/libgig-4.0.0/src/gig.cpp:3075
    #4 0x7fbea074c7d7 in gig::Region::Region(gig::Instrument*, RIFF::List*) /home/a/Documents/libgig-4.0.0/src/gig.cpp:2923
    #5 0x7fbea074ef4a in gig::Instrument::Instrument(gig::File*, RIFF::List*, RIFF::progress_t*) /home/a/Documents/libgig-4.0.0/src/gig.cpp:4404
    #6 0x7fbea0750fdc in gig::File::LoadInstruments(RIFF::progress_t*) /home/a/Documents/libgig-4.0.0/src/gig.cpp:5576
    #7 0x7fbea07226a0 in gig::File::GetFirstInstrument() /home/a/Documents/libgig-4.0.0/src/gig.cpp:5378
    #8 0x40fca6 in PrintInstruments(gig::File*) /home/a/Documents/libgig-4.0.0/src/tools/gigdump.cpp:205
    #9 0x4027aa in main /home/a/Documents/libgig-4.0.0/src/tools/gigdump.cpp:79
    #10 0x7fbe9fd70ec4 (/lib/x86_64-linux-gnu/libc.so.6+0x21ec4)
    #11 0x402e5c in _start (/home/a/Documents/libgig-4.0.0/src/tools/.libs/gigdump+0x402e5c)
Address 0x7ffc9ca05fa0 is located at offset 144 in frame <PrintInstruments> of T0's stack:
  This frame has 2 object(s):
    [32, 40) 'name'
    [96, 104) 'name'
HINT: this may be a false positive if your program uses some custom stack unwind mechanism or swapcontext
      (longjmp and C++ exceptions *are* supported)
SUMMARY: AddressSanitizer: stack-buffer-overflow /home/a/Documents/libgig-4.0.0/src/gig.cpp:2877 gig::DimensionRegion::CreateVelocityTable(gig::curve_type_t, unsigned char, unsigned char)
Shadow bytes around the buggy address:
  0x100013938ba0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x100013938bb0: 00 00 00 00 00 00 00 00 f1 f1 f1 f1 00 00 00 00
  0x100013938bc0: f3 f3 f3 f3 00 00 00 00 00 00 00 00 00 00 00 00
  0x100013938bd0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x100013938be0: 00 00 f1 f1 f1 f1 00 f4 f4 f4 f2 f2 f2 f2 00 f4
=>0x100013938bf0: f4 f4 f3 f3[f3]f3 00 00 00 00 00 00 00 00 00 00
  0x100013938c00: 00 00 f1 f1 f1 f1 00 00 f4 f4 f3 f3 f3 f3 00 00
  0x100013938c10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x100013938c20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x100013938c30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x100013938c40: 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
  Heap righ redzone:     fb
  Freed Heap region:     fd
  Stack left redzone:    f1
  Stack mid redzone:     f2
  Stack right redzone:   f3
  Stack partial redzone: f4
  Stack after return:    f5
  Stack use after scope: f8
  Global redzone:        f9
  Global init order:     f6
  Poisoned by user:      f7
  ASan internal:         fe
==40504== ABORTING


POC:
libgig_4.0.0_stack_buffer_overflow.gig
CVE:
CVE-2017-12951


3.
the LoadString function in helper.h in libgig 4.0.0 can cause a denial of service(Null pointer dereference and application crash) via a crafted gig file.


./gigdump libgig_4.0.0_null_pointer_dereference_2.gig


----debug info:----
Program received signal SIGSEGV, Segmentation fault.
LoadString (s="", ck=0x6095d0) at helper.h:148
148            if (str[len] == '\0') break;
(gdb) bt
#0  LoadString (s="", ck=0x6095d0) at helper.h:148
#1  DLS::Info::LoadString (ChunkID=ChunkID@entry=1146241865,
    lstINFO=lstINFO@entry=0x609330, s="") at DLS.cpp:307
#2  0x00007ffff7ba8095 in DLS::Info::Info (this=0x609220, list=<optimized out>)
    at DLS.cpp:263
#3  0x00007ffff7ba8448 in DLS::Resource::Resource (this=this@entry=0x609160,
    Parent=Parent@entry=0x0, lstResource=lstResource@entry=0x609090)
    at DLS.cpp:448
#4  0x00007ffff7baaa02 in DLS::File::File (this=0x609160, pRIFF=0x609090)
    at DLS.cpp:1435
#5  0x00007ffff7bbab2e in gig::File::File (this=0x609160,
    pRIFF=<optimized out>) at gig.cpp:5201
#6  0x0000000000401ee4 in main (argc=<optimized out>, argv=<optimized out>)
    at gigdump.cpp:70
(gdb) disassemble
Dump of assembler code for function DLS::Info::LoadString(unsigned int, RIFF::List*, std::string&):
   0x00007ffff7ba7f30 <+0>:push   %rbp
   0x00007ffff7ba7f31 <+1>:mov    %edi,%eax
   0x00007ffff7ba7f33 <+3>:mov    %rsi,%rdi
   0x00007ffff7ba7f36 <+6>:mov    %eax,%esi
   0x00007ffff7ba7f38 <+8>:push   %rbx
   0x00007ffff7ba7f39 <+9>:mov    %rdx,%rbx
   0x00007ffff7ba7f3c <+12>:sub    $0x8,%rsp
   0x00007ffff7ba7f40 <+16>:callq  0x7ffff7b9ed80 <_ZN4RIFF4List11GetSubChunkEj@plt>
   0x00007ffff7ba7f45 <+21>:test   %rax,%rax
   0x00007ffff7ba7f48 <+24>:mov    %rax,%rbp
   0x00007ffff7ba7f4b <+27>:je     0x7ffff7ba7fa8 <DLS::Info::LoadString(unsigned int, RIFF::List*, std::string&)+120>
   0x00007ffff7ba7f4d <+29>:mov    %rax,%rdi
   0x00007ffff7ba7f50 <+32>:callq  0x7ffff7b9e3e0 <_ZN4RIFF5Chunk13LoadChunkDataEv@plt>
   0x00007ffff7ba7f55 <+37>:mov    0xc(%rbp),%r10d
   0x00007ffff7ba7f59 <+41>:mov    %rax,%rsi
   0x00007ffff7ba7f5c <+44>:test   %r10d,%r10d
   0x00007ffff7ba7f5f <+47>:jle    0x7ffff7ba7faf <DLS::Info::LoadString(unsigned int, RIFF::List*, std::string&)+127>
---Type <return> to continue, or q <return> to quit---
=> 0x00007ffff7ba7f61 <+49>:cmpb   $0x0,(%rax)
   0x00007ffff7ba7f64 <+52>:je     0x7ffff7ba7faf <DLS::Info::LoadString(unsigned int, RIFF::List*, std::string&)+127>
   0x00007ffff7ba7f66 <+54>:mov    $0x1,%r9d
   0x00007ffff7ba7f6c <+60>:xor    %ecx,%ecx
   0x00007ffff7ba7f6e <+62>:jmp    0x7ffff7ba7f7e <DLS::Info::LoadString(unsigned int, RIFF::List*, std::string&)+78>
   0x00007ffff7ba7f70 <+64>:cmpb   $0x0,(%rsi,%r9,1)
   0x00007ffff7ba7f75 <+69>:lea    0x1(%r9),%r8
   0x00007ffff7ba7f79 <+73>:je     0x7ffff7ba7fa0 <DLS::Info::LoadString(unsigned int, RIFF::List*, std::string&)+112>
   0x00007ffff7ba7f7b <+75>:mov    %r8,%r9
   0x00007ffff7ba7f7e <+78>:add    $0x1,%ecx
   0x00007ffff7ba7f81 <+81>:cmp    %r10d,%ecx
   0x00007ffff7ba7f84 <+84>:jne    0x7ffff7ba7f70 <DLS::Info::LoadString(unsigned int, RIFF::List*, std::string&)+64>
   0x00007ffff7ba7f86 <+86>:movslq %ecx,%rdx
   0x00007ffff7ba7f89 <+89>:mov    %rbx,%rdi
   0x00007ffff7ba7f8c <+92>:callq  0x7ffff7b9f030 <_ZNSs6assignEPKcm@plt>
   0x00007ffff7ba7f91 <+97>:add    $0x8,%rsp
   0x00007ffff7ba7f95 <+101>:mov    %rbp,%rdi
   0x00007ffff7ba7f98 <+104>:pop    %rbx
   0x00007ffff7ba7f99 <+105>:pop    %rbp
---Type <return> to continue, or q <return> to quit---q
Quit
(gdb) i r
rax            0x00
rbx            0x6092386328888
rcx            0x7ffff739f9f7140737341159927
rdx            0x7ffff5d9f000140737318088704
rsi            0x00
rdi            0x7ffff5d9f000140737318088704
rbp            0x6095d00x6095d0
rsp            0x7fffffffdd800x7fffffffdd80
r8             0xffffffff4294967295
r9             0x00
r10            0x100001a16777242
r11            0x247583
r12            0x6092206328864
r13            0x7fffffffdfa0140737488347040
r14            0x00
r15            0x6091a06328736
rip            0x7ffff7ba7f610x7ffff7ba7f61 <DLS::Info::LoadString(unsigned int, RIFF::List*, std::string&)+49>
eflags         0x10202[ IF RF ]
cs             0x3351
ss             0x2b43
ds             0x00
es             0x00
---Type <return> to continue, or q <return> to quit---
fs             0x00
gs             0x00
(gdb)


ASAN:SIGSEGV
=================================================================
==41244== ERROR: AddressSanitizer: SEGV on unknown address 0x000000000000 (pc 0x7f260c0db52b sp 0x7fffc62477e0 bp 0x600e0000ded0 T0)
AddressSanitizer can not provide additional info.
    #0 0x7f260c0db52a in LoadString /home/a/Documents/libgig-4.0.0/src/helper.h:148
    #1 0x7f260c0db52a in DLS::Info::LoadString(unsigned int, RIFF::List*, std::string&) /home/a/Documents/libgig-4.0.0/src/DLS.cpp:307
    #2 0x7f260c0dbfcb in DLS::Info::Info(RIFF::List*) /home/a/Documents/libgig-4.0.0/src/DLS.cpp:263
    #3 0x7f260c0dcf82 in DLS::Resource::Resource(DLS::Resource*, RIFF::List*) /home/a/Documents/libgig-4.0.0/src/DLS.cpp:448
    #4 0x7f260c0ee958 in DLS::File::File(RIFF::File*) /home/a/Documents/libgig-4.0.0/src/DLS.cpp:1435
    #5 0x7f260c173e75 in gig::File::File(RIFF::File*) /home/a/Documents/libgig-4.0.0/src/gig.cpp:5201
    #6 0x40275a in main /home/a/Documents/libgig-4.0.0/src/tools/gigdump.cpp:70
    #7 0x7f260b7c3ec4 (/lib/x86_64-linux-gnu/libc.so.6+0x21ec4)
    #8 0x402e5c in _start (/home/a/Documents/libgig-4.0.0/src/tools/.libs/gigdump+0x402e5c)
SUMMARY: AddressSanitizer: SEGV /home/a/Documents/libgig-4.0.0/src/helper.h:148 LoadString
==41244== ABORTING


POC:
libgig_4.0.0_null_pointer_dereference_2.gig
CVE:
CVE-2017-12952


4.
the gig::Instrument::UpdateRegionKeyTable function in gig.cpp in libgig 4.0.0 can cause a denial of service(invalid memory write and application crash) via a crafted gig file.


./gigdump libgig_4.0.0_invalid_memory_write.gig


----debug info:----
Program received signal SIGSEGV, Segmentation fault.
gig::Instrument::UpdateRegionKeyTable (this=this@entry=0x60a1a0) at gig.cpp:4445
4445                RegionKeyTable[iKey] = pRegion;
(gdb) bt
#0  gig::Instrument::UpdateRegionKeyTable (this=this@entry=0x60a1a0)
    at gig.cpp:4445
#1  0x00007ffff7bc0b75 in gig::Instrument::Instrument (this=0x60a1a0,
    pFile=<optimized out>, insList=0x60a0c0, pProgress=0x7fffffffdd90)
    at gig.cpp:4409
#2  0x00007ffff7bc103e in gig::File::LoadInstruments (this=0x609160,
    pProgress=0x0) at gig.cpp:5576
#3  0x00007ffff7bbade6 in gig::File::GetFirstInstrument (
    this=this@entry=0x609160) at gig.cpp:5378
#4  0x000000000040533b in PrintInstruments (gig=gig@entry=0x609160)
    at gigdump.cpp:205
#5  0x0000000000401f34 in main (argc=<optimized out>, argv=<optimized out>)
    at gigdump.cpp:79
(gdb) disassemble
Dump of assembler code for function gig::Instrument::UpdateRegionKeyTable():
   0x00007ffff7bba240 <+0>:xor    %eax,%eax
   0x00007ffff7bba242 <+2>:nopw   0x0(%rax,%rax,1)
   0x00007ffff7bba248 <+8>:movq   $0x0,0x80(%rdi,%rax,1)
   0x00007ffff7bba254 <+20>:add    $0x8,%rax
   0x00007ffff7bba258 <+24>:cmp    $0x400,%rax
   0x00007ffff7bba25e <+30>:jne    0x7ffff7bba248 <gig::Instrument::UpdateRegionKeyTable()+8>
   0x00007ffff7bba260 <+32>:mov    0x60(%rdi),%r9
   0x00007ffff7bba264 <+36>:mov    (%r9),%r8
   0x00007ffff7bba267 <+39>:cmp    %r9,%r8
   0x00007ffff7bba26a <+42>:je     0x7ffff7bba2a4 <gig::Instrument::UpdateRegionKeyTable()+100>
   0x00007ffff7bba26c <+44>:nopl   0x0(%rax)
   0x00007ffff7bba270 <+48>:mov    0x10(%r8),%rcx
   0x00007ffff7bba274 <+52>:movzwl 0x78(%rcx),%eax
   0x00007ffff7bba278 <+56>:movzwl 0x7a(%rcx),%esi
   0x00007ffff7bba27c <+60>:cmp    %esi,%eax
   0x00007ffff7bba27e <+62>:jg     0x7ffff7bba29a <gig::Instrument::UpdateRegionKeyTable()+90>
   0x00007ffff7bba280 <+64>:add    $0x1,%esi
   0x00007ffff7bba283 <+67>:nopl   0x0(%rax,%rax,1)
   0x00007ffff7bba288 <+72>:movslq %eax,%rdx
---Type <return> to continue, or q <return> to quit---
   0x00007ffff7bba28b <+75>:add    $0x1,%eax
   0x00007ffff7bba28e <+78>:cmp    %esi,%eax
=> 0x00007ffff7bba290 <+80>:mov    %rcx,0x80(%rdi,%rdx,8)
   0x00007ffff7bba298 <+88>:jne    0x7ffff7bba288 <gig::Instrument::UpdateRegionKeyTable()+72>
   0x00007ffff7bba29a <+90>:mov    (%r8),%r8
   0x00007ffff7bba29d <+93>:cmp    %r8,%r9
   0x00007ffff7bba2a0 <+96>:jne    0x7ffff7bba270 <gig::Instrument::UpdateRegionKeyTable()+48>
   0x00007ffff7bba2a2 <+98>:repz retq
   0x00007ffff7bba2a4 <+100>:repz retq
End of assembler dump.
(gdb) i r
rax            0x3fbd16317
rbx            0x60a1a06332832
rcx            0x60d5806346112
rdx            0x3fbc16316
rsi            0x420116897
rdi            0x60a1a06332832
rbp            0x7fffffffdd900x7fffffffdd90
rsp            0x7fffffffdd080x7fffffffdd08
r8             0x60e7406350656
r9             0x60b0f06336752
r10            0x7fffffffdad0140737488345808
r11            0x7ffff7bba240140737349657152
r12            0x00
r13            0x60a0c06332608
r14            0x60a9806334848
r15            0x60d5806346112
rip            0x7ffff7bba2900x7ffff7bba290 <gig::Instrument::UpdateRegionKeyTable()+80>
eflags         0x10283[ CF SF IF RF ]
cs             0x3351
ss             0x2b43
ds             0x00
es             0x00
---Type <return> to continue, or q <return> to quit---
fs             0x00
gs             0x00
(gdb)


ASAN:SIGSEGV
=================================================================
==43045== ERROR: AddressSanitizer: SEGV on unknown address 0x60460003dd80 (pc 0x7fb8f7cfcd88 sp 0x7ffcb179db10 bp 0x60460001f500 T0)
AddressSanitizer can not provide additional info.
    #0 0x7fb8f7cfcd87 in gig::Instrument::UpdateRegionKeyTable() /home/a/Documents/libgig-4.0.0/src/gig.cpp:4444
    #1 0x7fb8f7d2efe2 in gig::Instrument::Instrument(gig::File*, RIFF::List*, RIFF::progress_t*) /home/a/Documents/libgig-4.0.0/src/gig.cpp:4409
    #2 0x7fb8f7d30fdc in gig::File::LoadInstruments(RIFF::progress_t*) /home/a/Documents/libgig-4.0.0/src/gig.cpp:5576
    #3 0x7fb8f7d026a0 in gig::File::GetFirstInstrument() /home/a/Documents/libgig-4.0.0/src/gig.cpp:5378
    #4 0x40fca6 in PrintInstruments(gig::File*) /home/a/Documents/libgig-4.0.0/src/tools/gigdump.cpp:205
    #5 0x4027aa in main /home/a/Documents/libgig-4.0.0/src/tools/gigdump.cpp:79
    #6 0x7fb8f7350ec4 (/lib/x86_64-linux-gnu/libc.so.6+0x21ec4)
    #7 0x402e5c in _start (/home/a/Documents/libgig-4.0.0/src/tools/.libs/gigdump+0x402e5c)
SUMMARY: AddressSanitizer: SEGV /home/a/Documents/libgig-4.0.0/src/gig.cpp:4445 gig::Instrument::UpdateRegionKeyTable()
==43045== ABORTING


POC:
libgig_4.0.0_invalid_memory_write.gig
CVE:
CVE-2017-12953


5.
the gig::Region::GetSampleFromWavePool function in gig.cpp in gig.cpp in libgig 4.0.0 can cause a denial of service(invalid memory read and application crash) via a crafted gig file.


./gigdump libgig_4.0.0_invalid_memory_read.gig


----debug info:----
Program received signal SIGSEGV, Segmentation fault.
gig::Region::GetSampleFromWavePool (this=0x609160, this@entry=0x612520,
    WavePoolTableIndex=0, pProgress=pProgress@entry=0x0) at gig.cpp:3849
3849        unsigned long soughtoffset = file->pWavePoolTable[WavePoolTableIndex];
(gdb) bt
#0  gig::Region::GetSampleFromWavePool (this=0x609160, this@entry=0x612520,
    WavePoolTableIndex=0, pProgress=pProgress@entry=0x0) at gig.cpp:3849
#1  0x00007ffff7bc07df in gig::Region::Region (this=0x612520,
    pInstrument=<optimized out>, rgnList=0x6100f0) at gig.cpp:2970
#2  0x00007ffff7bc0b36 in gig::Instrument::Instrument (this=0x60ef80,
    pFile=<optimized out>, insList=0x60eea0, pProgress=0x7fffffffdd90)
    at gig.cpp:4404
#3  0x00007ffff7bc103e in gig::File::LoadInstruments (this=0x609160,
    pProgress=0x0) at gig.cpp:5576
#4  0x00007ffff7bbade6 in gig::File::GetFirstInstrument (
    this=this@entry=0x609160) at gig.cpp:5378
#5  0x000000000040533b in PrintInstruments (gig=gig@entry=0x609160)
    at gigdump.cpp:205
#6  0x0000000000401f34 in main (argc=<optimized out>, argv=<optimized out>)
    at gigdump.cpp:79
(gdb) disassemble
Dump of assembler code for function gig::Region::GetSampleFromWavePool(unsigned int, RIFF::progress_t*):
   0x00007ffff7bbac00 <+0>:cmp    $0xffffffff,%esi
   0x00007ffff7bbac03 <+3>:je     0x7ffff7bbac63 <gig::Region::GetSampleFromWavePool(unsigned int, RIFF::progress_t*)+99>
   0x00007ffff7bbac05 <+5>:push   %r12
   0x00007ffff7bbac07 <+7>:push   %rbp
   0x00007ffff7bbac08 <+8>:push   %rbx
   0x00007ffff7bbac09 <+9>:mov    0x18(%rdi),%rax
   0x00007ffff7bbac0d <+13>:mov    0x18(%rax),%rbx
   0x00007ffff7bbac11 <+17>:mov    0x78(%rbx),%rax
   0x00007ffff7bbac15 <+21>:test   %rax,%rax
   0x00007ffff7bbac18 <+24>:je     0x7ffff7bbac5c <gig::Region::GetSampleFromWavePool(unsigned int, RIFF::progress_t*)+92>
   0x00007ffff7bbac1a <+26>:mov    %esi,%ecx
   0x00007ffff7bbac1c <+28>:mov    %rbx,%rdi
   0x00007ffff7bbac1f <+31>:mov    %rdx,%rsi
=> 0x00007ffff7bbac22 <+34>:mov    (%rax,%rcx,4),%ebp
   0x00007ffff7bbac25 <+37>:mov    0x80(%rbx),%rax
   0x00007ffff7bbac2c <+44>:mov    (%rax,%rcx,4),%r12d
   0x00007ffff7bbac30 <+48>:callq  0x7ffff7b9e400 <_ZN3gig4File14GetFirstSampleEPN4RIFF10progress_tE@plt>
   0x00007ffff7bbac35 <+53>:test   %rax,%rax
---Type <return> to continue, or q <return> to quit---q
Quit
(gdb) i r
rax            0x609f806332288
rbx            0x6091606328672
rcx            0xff0000004278190080
rdx            0x00
rsi            0x00
rdi            0x6091606328672
rbp            0x00x0
rsp            0x7fffffffdc900x7fffffffdc90
r8             0x00
r9             0x22
r10            0x00
r11            0x246582
r12            0x6131906369680
r13            0x6125206366496
r14            0x00
r15            0x00
rip            0x7ffff7bbac220x7ffff7bbac22 <gig::Region::GetSampleFromWavePool(unsigned int, RIFF::progress_t*)+34>
eflags         0x10202[ IF RF ]
cs             0x3351
ss             0x2b43
ds             0x00
es             0x00
---Type <return> to continue, or q <return> to quit---
fs             0x00
gs             0x00
(gdb)


ASAN:SIGSEGV
=================================================================
==44028== ERROR: AddressSanitizer: SEGV on unknown address 0x6009fc00ed70 (pc 0x7fea916446ac sp 0x7ffd026ec040 bp 0x0c08c0003ea3 T0)
AddressSanitizer can not provide additional info.
    #0 0x7fea916446ab in gig::Region::GetSampleFromWavePool(unsigned int, RIFF::progress_t*) /home/a/Documents/libgig-4.0.0/src/gig.cpp:3850
    #1 0x7fea91670247 in gig::Region::Region(gig::Instrument*, RIFF::List*) /home/a/Documents/libgig-4.0.0/src/gig.cpp:2970
    #2 0x7fea91671f4a in gig::Instrument::Instrument(gig::File*, RIFF::List*, RIFF::progress_t*) /home/a/Documents/libgig-4.0.0/src/gig.cpp:4404
    #3 0x7fea91673fdc in gig::File::LoadInstruments(RIFF::progress_t*) /home/a/Documents/libgig-4.0.0/src/gig.cpp:5576
    #4 0x7fea916456a0 in gig::File::GetFirstInstrument() /home/a/Documents/libgig-4.0.0/src/gig.cpp:5378
    #5 0x40fca6 in PrintInstruments(gig::File*) /home/a/Documents/libgig-4.0.0/src/tools/gigdump.cpp:205
    #6 0x4027aa in main /home/a/Documents/libgig-4.0.0/src/tools/gigdump.cpp:79
    #7 0x7fea90c93ec4 (/lib/x86_64-linux-gnu/libc.so.6+0x21ec4)
    #8 0x402e5c in _start (/home/a/Documents/libgig-4.0.0/src/tools/.libs/gigdump+0x402e5c)
SUMMARY: AddressSanitizer: SEGV /home/a/Documents/libgig-4.0.0/src/gig.cpp:3849 gig::Region::GetSampleFromWavePool(unsigned int, RIFF::progress_t*)
==44028== ABORTING


POC:
libgig_4.0.0_invalid_memory_read.gig
CVE:
CVE-2017-12954


Proof of Concept:
https://github.com/offensive-security/exploitdb-bin-sploits/raw/master/bin-sploits/42546.zip
