New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Heap overflows in parser.c #68

Closed
mboehme opened this Issue Mar 21, 2017 · 3 comments

Comments

Projects
None yet
3 participants
@mboehme

mboehme commented Mar 21, 2017

Dear all,

The following bugs were found with AFLGo, a directed version of the fuzzer AFL / AFLFast. Thanks also to Van-Thuan Pham.

This issues are related to #58. The Libming utility listswf crashes due to a heap-based buffer overflow in the function parseSWF_RGBA and several other functions in parser.c. AddressSanitizer flags them as invalid writes "of size 1" but the heap can be actually be written to multiple times (e.g., in each line of parser.c:58-71). The overflows are caused by a pointer behind the bounds of a statically allocated array of structs of type SWF_GRADIENTRECORD.

Sample crash-inducing input: libming1.swf.zip

$ util/listswf libming1.swf
read.c:109:14: runtime error: shift exponent -1 is negative
read.c:110:20: runtime error: left shift of 1 by 31 places cannot be represented in type 'int'
read.c:110:16: runtime error: signed integer overflow: 1389485020 - -2147483648 cannot be represented in type 'int'
205 gradients in SWF_MORPHGRADiENT, expected a max of 8parser.c:786:40: runtime error: index 9 out of bounds for type 'SWF_MORPHGRADIENTRECORD [8]'
203 gradients in SWF_MORPHGRADiENT, expected a max of 8=================================================================
==179946==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x62e00000b298 at pc 0x0000005b1be8 bp 0x7ffc849e8990 sp 0x7ffc849e8988
WRITE of size 1 at 0x62e00000b298 thread T0
    #0 0x5b1be7 in parseSWF_RGBA /home/ubuntu/subjects/build-asan/libming/util/parser.c:68:14
    #1 0x5f004a in parseSWF_MORPHGRADIENTRECORD /home/ubuntu/subjects/build-asan/libming/util/parser.c:771:3
    #2 0x5f0c1f in parseSWF_MORPHGRADIENT /home/ubuntu/subjects/build-asan/libming/util/parser.c:786:5
    #3 0x5ee190 in parseSWF_MORPHFILLSTYLE /home/ubuntu/subjects/build-asan/libming/util/parser.c:802:7
    #4 0x5f1bbe in parseSWF_MORPHFILLSTYLES /home/ubuntu/subjects/build-asan/libming/util/parser.c:829:7
    #5 0x634ee5 in parseSWF_DEFINEMORPHSHAPE /home/ubuntu/subjects/build-asan/libming/util/parser.c:2185:3
    #6 0x543923 in blockParse /home/ubuntu/subjects/build-asan/libming/util/blocktypes.c:145:14
    #7 0x52b2a9 in readMovie /home/ubuntu/subjects/build-asan/libming/util/main.c:265:11
    #8 0x528f82 in main /home/ubuntu/subjects/build-asan/libming/util/main.c:350:2
    #9 0x7ff0c21cdf44 in __libc_start_main /build/eglibc-oGUzwX/eglibc-2.19/csu/libc-start.c:287
    #10 0x4bdf5c in _start (/home/ubuntu/subjects/build-asan/libming/util/listswf+0x4bdf5c)

0x62e00000b298 is located 0 bytes to the right of 44696-byte region [0x62e000000400,0x62e00000b298)
allocated by thread T0 here:
    #0 0x4a0a40 in calloc (/home/ubuntu/subjects/build-asan/libming/util/listswf+0x4a0a40)
    #1 0x5f17b2 in parseSWF_MORPHFILLSTYLES /home/ubuntu/subjects/build-asan/libming/util/parser.c:826:28
    #2 0x634ee5 in parseSWF_DEFINEMORPHSHAPE /home/ubuntu/subjects/build-asan/libming/util/parser.c:2185:3
    #3 0x543923 in blockParse /home/ubuntu/subjects/build-asan/libming/util/blocktypes.c:145:14
    #4 0x52b2a9 in readMovie /home/ubuntu/subjects/build-asan/libming/util/main.c:265:11
    #5 0x528f82 in main /home/ubuntu/subjects/build-asan/libming/util/main.c:350:2
    #6 0x7ff0c21cdf44 in __libc_start_main /build/eglibc-oGUzwX/eglibc-2.19/csu/libc-start.c:287

SUMMARY: AddressSanitizer: heap-buffer-overflow /home/ubuntu/subjects/build-asan/libming/util/parser.c:68 parseSWF_RGBA

The bugs are fixed by the following patch (preventing the pointer behind the array bounds):

diff --git a/util/parser.c b/util/parser.c
index 96b1232..b8662ca 100644
--- a/util/parser.c
+++ b/util/parser.c
@@ -439,6 +439,7 @@ parseSWF_FOCALGRADIENT (FILE * f, struct SWF_FOCALGRADIENT *gradient, int level)
   gradient->NumGradients = readBits (f, 4);
   if(gradient->NumGradients > 15) {
          fprintf(stderr, "%d gradients in SWF_FOCALGRADIENT, expected a max of 15\n", gradient->NumGradients );
+         gradient->NumGradients = 15;
          /*exit(1);*/
   }
 
@@ -457,6 +458,7 @@ parseSWF_GRADIENT (FILE * f, struct SWF_GRADIENT *gradient, int level)
   gradient->NumGradients = readBits (f, 4);
   if((gradient->NumGradients > 8  && level < 4) || (gradient->NumGradients > 15  && level == 4)) {
          fprintf(stderr, "%d gradients in SWF_GRADiENT, expected a max of %d\n", gradient->NumGradients, level<4 ? 8 : 15 );
+         gradient->NumGradients = 8;
          /*exit(1);*/
   }
 
@@ -780,6 +782,7 @@ parseSWF_MORPHGRADIENT (FILE * f, struct SWF_MORPHGRADIENT *gradient)
   gradient->NumGradients = readUInt8 (f);
   if( gradient->NumGradients > 8 ) {
          fprintf(stderr, "%d gradients in SWF_MORPHGRADiENT, expected a max of 8", gradient->NumGradients);
+          gradient->NumGradients = 8;
          /*exit(1);*/
   }
   for (i = 0; i < gradient->NumGradients; i++)

Best regards,

  • Marcel

Marcel Böhme
Senior Research Fellow
TSUNAMi Research Centre
National University of Singapore

@strk strk self-assigned this Mar 21, 2017

@strk strk closed this in ea70414 Mar 21, 2017

@strk

This comment has been minimized.

Show comment
Hide comment
@strk

strk Mar 21, 2017

Member

Thanks !

Member

strk commented Mar 21, 2017

Thanks !

@asarubbo

This comment has been minimized.

Show comment
Hide comment
@asarubbo

asarubbo Apr 7, 2017

This is CVE-2017-7578

asarubbo commented Apr 7, 2017

This is CVE-2017-7578

@strk

This comment has been minimized.

Show comment
Hide comment
@strk

strk Apr 7, 2017

Member

Noted in NEWS with 52243ad

Member

strk commented Apr 7, 2017

Noted in NEWS with 52243ad

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment