diff --git a/NEWS b/NEWS index 129d55fe..7eb256ca 100644 --- a/NEWS +++ b/NEWS @@ -43,6 +43,11 @@ with empty acts (NULL act->p.String). Perform deep copy in pushdup, instead of shallow copy (issue #121). * Fix heap-buffer-overflow in getString (CVE-2018-7867, issue #116). + * Fix null pointer dereference in getInt (CVE-2018-9132, issue #133). + * Fix heap-use-after-free in decompileJUMP (CVE-2018-9009, issue #131). + * Fix memory exhaustion in parseSWF_ACTIONRECORD (CVE-2018-7876, #109). + * Fix heap-buffer-overflow in function getString (CVE-2018-7873, #111). + * Fix null pointer dereference in newVar3 (CVE-2018-7866, #118). 0.4.8 - 2017-04-07 diff --git a/util/decompile.c b/util/decompile.c index e9341356..cf1a372d 100644 --- a/util/decompile.c +++ b/util/decompile.c @@ -358,9 +358,19 @@ getString(struct SWF_ACTIONPUSHPARAM *act) return t; } case PUSH_INT: /* INTEGER */ - t=malloc(10); /* 32-bit decimal */ - sprintf(t,"%ld", act->p.Integer ); + { + char length_finder[1]; + int needed_length = snprintf(length_finder, 1, "%ld", act->p.Integer) + 1; + if (needed_length <= 0) + { + SWF_warn("WARNING: could not evaluate size of buffer (memory issue ?).\n"); + break; + } + + t = malloc(needed_length); + sprintf(t, "%ld", act->p.Integer ); return t; + } case PUSH_CONSTANT: /* CONSTANT8 */ if (act->p.Constant8 > poolcounter) { @@ -387,7 +397,14 @@ getString(struct SWF_ACTIONPUSHPARAM *act) case 12: case 11: /* INCREMENTED or DECREMENTED VARIABLE */ case PUSH_VARIABLE: /* VARIABLE */ - return act->p.String; + if (!act->p.String) + { + SWF_warn("WARNING: Call to getString with PUSH_VARIABLE defining NULL string.\n"); + break; + } + t=malloc(strlen(act->p.String)+1); /* NULL character */ + strcpy(t,act->p.String); + return t; default: fprintf (stderr," Can't get string for type: %d\n", act->Type); break; @@ -481,7 +498,15 @@ getInt(struct SWF_ACTIONPUSHPARAM *act) case PUSH_NULL: /* NULL */ return 0; case PUSH_REGISTER: /* REGISTER */ - return getInt(regs[act->p.RegisterNumber]); + if (regs[act->p.RegisterNumber]) + { + return getInt(regs[act->p.RegisterNumber]); + } + else + { + SWF_warn("WARNING: retrieving undefined register values.\n"); + break; + } case PUSH_DOUBLE: /* DOUBLE */ return (int)act->p.Double; case PUSH_INT: /* INTEGER */ @@ -939,6 +964,24 @@ decompileGETURL2 (SWF_ACTION *act) return 0; } +static inline int Offset(SWF_ACTION *actions, int n, int maxn) +{ + if(!n || n >= maxn) + { +#if DEBUG + SWF_warn("Offset: want %i, max %i\n", n, maxn); +#endif + return -999; + } else if (n < 1) { + +#if DEBUG + SWF_warn("Offset: want %i < 1\n", n); +#endif + return -998; + } + return actions[n].SWF_ACTIONRECORD.Offset; +} + static inline int OpCode(SWF_ACTION *actions, int n, int maxn) { if(!n || n >= maxn) @@ -1929,7 +1972,7 @@ decompileJUMP(int n, SWF_ACTION *actions, int maxn) { sactif = (struct SWF_ACTIONIF *)&(actions[n+i+j]); /* chk whether last jump does lead us back to start of loop */ - if (sactif->Actions[sactif->numActions-1].SWF_ACTIONRECORD.ActionCode==SWFACTION_JUMP + if (OpCode(sactif->Actions, sactif->numActions-1, maxn) == SWFACTION_JUMP && sactif->Actions[sactif->numActions-1].SWF_ACTIONJUMP.BranchOffset+ sactif->Actions[sactif->numActions-1].SWF_ACTIONJUMP.Offset== actions[n].SWF_ACTIONRECORD.Offset ) @@ -2101,7 +2144,7 @@ decompile_SWITCH(int n, SWF_ACTION *actions, int maxn, int off1end) int offSave; for (i=0; iActions[sact->numActions-1].SWF_ACTIONRECORD.ActionCode == SWFACTION_JUMP) && + (OpCode(sact->Actions, sact->numActions-1, maxn) == SWFACTION_JUMP) && ( (sact->Actions[sact->numActions-1].SWF_ACTIONJUMP.Offset + sact->Actions[sact->numActions-1].SWF_ACTIONJUMP.BranchOffset) < actions[n].SWF_ACTIONRECORD.Offset) && isLogicalOp(sact->numActions-2, sact->Actions, maxn) ) @@ -2424,7 +2467,7 @@ decompileIF(int n, SWF_ACTION *actions, int maxn) */ if( isLogicalOp(n-1, actions, maxn) && - ( (sact->Actions[sact->numActions-1].SWF_ACTIONRECORD.ActionCode == SWFACTION_JUMP) && + ((OpCode(sact->Actions, sact->numActions-1, maxn) == SWFACTION_JUMP) && sact->Actions[sact->numActions-1].SWF_ACTIONJUMP.BranchOffset < 0) ) { if(0) dumpRegs(); @@ -2460,7 +2503,7 @@ decompileIF(int n, SWF_ACTION *actions, int maxn) } { // WTF ??? #define SOME_IF_DEBUG 0 /* coders only */ - int has_else_or_break= ((sact->Actions[sact->numActions-1].SWF_ACTIONRECORD.ActionCode == SWFACTION_JUMP) && + int has_else_or_break= ((OpCode(sact->Actions, sact->numActions-1, maxn) == SWFACTION_JUMP) && (sact->Actions[sact->numActions-1].SWF_ACTIONJUMP.BranchOffset > 0 )) ? 1:0; int has_lognot=(OpCode(actions, n-1, maxn) == SWFACTION_LOGICALNOT) ? 1:0; int else_action_cnt=0,is_logor=0,is_logand=0,sbi,sbe; @@ -3154,7 +3197,7 @@ decompileSETTARGET(int n, SWF_ACTION *actions, int maxn, int is_type2) { INDENT println("tellTarget('%s') {" ,name); - while(action_cnt+n