VYPR
High severityNVD Advisory· Published May 9, 2018· Updated Aug 5, 2024

CVE-2018-0946

CVE-2018-0946

Description

A remote code execution vulnerability exists in Microsoft Edge's and ChakraCore's scripting engine due to improper memory object handling, allowing attackers to execute arbitrary code via a crafted web page.

AI Insight

LLM-synthesized narrative grounded in this CVE's description and references.

A remote code execution vulnerability exists in Microsoft Edge's and ChakraCore's scripting engine due to improper memory object handling, allowing attackers to execute arbitrary code via a crafted web page.

Vulnerability

CVE-2018-0946 is a memory corruption vulnerability in the scripting engine (Chakra) used by Microsoft Edge and the open-source ChakraCore library [1][2]. The bug is triggered when the scripting engine improperly handles objects in memory while processing specially crafted JavaScript content [3]. The vulnerability affects all supported versions of Microsoft Edge on Windows 10, as well as ChakraCore prior to security updates released in May 2018 [2].

Exploitation

An attacker must host a malicious web page or inject script into a trusted site that the victim then accesses through Microsoft Edge [3]. No additional authentication or user interaction beyond opening the crafted page is required, as the scripting engine automatically parses the JavaScript, triggering the memory corruption condition [1]. The vulnerability was credited to Lokihardt of Google Project Zero, indicating a capable researcher with detailed understanding of the flaw [2].

Impact

Successful exploitation grants the attacker arbitrary code execution within the context of the current user in the Edge sandbox [3]. The attacker could then install programs, view, change, or delete data, or create new accounts with the user's full rights [1]. This represents a complete compromise of client confidentiality, integrity, and availability.

Mitigation

Microsoft released security updates in May 2018 as part of Patch Tuesday (May 8, 2018) that address this vulnerability [3]. Affected versions of Microsoft Edge are updated via Windows Update; ChakraCore users should update to the latest patched version. No workarounds are documented in the available references. ChakraCore 1.11 entered end-of-life with security update support ending March 9, 2021 [4].

AI Insight generated on May 22, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
Microsoft.ChakraCoreNuGet
< 1.8.41.8.4

Affected products

3

Patches

1
bee1e247bf6a

[CVE-2018-8130] [CVE-2018-0946] move allocators to ServerScriptContext, add missing marshalling code

https://github.com/chakra-core/ChakraCoreMichael HolmanMar 20, 2018via ghsa
13 files changed · +52 39
  • lib/Backend/NativeCodeGenerator.cpp+1 2 modified
    @@ -3257,8 +3257,7 @@ NativeCodeGenerator::FreeNativeCodeGenAllocation(void* codeAddress)
     #if PDATA_ENABLED && defined(_WIN32)
             DelayDeletingFunctionTable::Clear();
     #endif
    -        ThreadContext * context = this->scriptContext->GetThreadContext();
    -        HRESULT hr = JITManager::GetJITManager()->FreeAllocation(context->GetRemoteThreadContextAddr(), (intptr_t)codeAddress);
    +        HRESULT hr = JITManager::GetJITManager()->FreeAllocation(this->scriptContext->GetRemoteScriptAddr(), (intptr_t)codeAddress);
             JITManager::HandleServerCallResult(hr, RemoteCallType::MemFree);
         }
         else if(this->backgroundAllocators)
    
  • lib/Backend/ServerScriptContext.cpp+15 1 modified
    @@ -26,13 +26,19 @@ ServerScriptContext::ServerScriptContext(ScriptContextDataIDL * contextData, Ser
         m_asmJsInterpreterThunkBufferManager(&m_sourceCodeArena, threadContextInfo->GetThunkPageAllocators(), nullptr, threadContextInfo, _u("Asm.js interpreter thunk buffer"), GetThreadContext()->GetProcessHandle()),
         m_domFastPathHelperMap(nullptr),
         m_moduleRecords(&HeapAllocator::Instance),
    +    m_codeGenAlloc(nullptr, nullptr, threadContextInfo, threadContextInfo->GetCodePageAllocators(), threadContextInfo->GetProcessHandle()),
         m_globalThisAddr(0),
     #ifdef PROFILE_EXEC
         m_codeGenProfiler(nullptr),
     #endif
         m_refCount(0),
         m_isClosed(false)
     {
    +
    +#if !TARGET_64 && _CONTROL_FLOW_GUARD
    +    m_codeGenAlloc.canCreatePreReservedSegment = threadContextInfo->CanCreatePreReservedSegment();
    +#endif
    +
     #ifdef PROFILE_EXEC
         if (Js::Configuration::Global.flags.IsEnabled(Js::ProfileFlag))
         {
    @@ -357,7 +363,9 @@ ServerScriptContext::Close()
     {
         Assert(!IsClosed());
         m_isClosed = true;
    -    
    +
    +    m_codeGenAlloc.emitBufferManager.Decommit();
    +
     #ifdef STACK_BACK_TRACE
         ServerContextManager::RecordCloseContext(this);
     #endif
    @@ -381,6 +389,12 @@ ServerScriptContext::Release()
         }
     }
     
    +OOPCodeGenAllocators *
    +ServerScriptContext::GetCodeGenAllocators()
    +{
    +    return &m_codeGenAlloc;
    +}
    +
     Field(Js::Var)*
     ServerScriptContext::GetModuleExportSlotArrayAddress(uint moduleIndex, uint slotIndex)
     {
    
  • lib/Backend/ServerScriptContext.h+3 0 modified
    @@ -87,6 +87,7 @@ class ServerScriptContext : public ScriptContextInfo
         Js::ScriptContextProfiler *  GetCodeGenProfiler() const;
         ServerThreadContext* GetThreadContext() { return threadContextHolder.threadContextInfo; }
     
    +    OOPCodeGenAllocators * GetCodeGenAllocators();
         ArenaAllocator * GetSourceCodeArena();
         void Close();
         void AddRef();
    @@ -107,6 +108,8 @@ class ServerScriptContext : public ScriptContextInfo
     
         uint m_refCount;
     
    +    OOPCodeGenAllocators m_codeGenAlloc;
    +
         bool m_isPRNGSeeded;
         bool m_isClosed;
     #endif
    
  • lib/Backend/ServerThreadContext.cpp+12 15 modified
    @@ -14,24 +14,21 @@ ServerThreadContext::ServerThreadContext(ThreadContextDataIDL* data, ProcessCont
         m_numericPropertyBV(nullptr),
         m_preReservedSectionAllocator(processContext->processHandle),
         m_sectionAllocator(processContext->processHandle),
    -    m_thunkPageAllocators(nullptr, /* allocXData */ false, &m_sectionAllocator, nullptr, processContext->processHandle),
         m_codePageAllocators(nullptr, ALLOC_XDATA, &m_sectionAllocator, &m_preReservedSectionAllocator, processContext->processHandle),
    +    m_thunkPageAllocators(nullptr, /* allocXData */ false, &m_sectionAllocator, nullptr, processContext->processHandle),
     #if defined(_CONTROL_FLOW_GUARD) && !defined(_M_ARM)
         m_jitThunkEmitter(this, &m_sectionAllocator, processContext->processHandle),
     #endif
    -    m_codeGenAlloc(nullptr, nullptr, this, &m_codePageAllocators, processContext->processHandle),
         m_pageAlloc(nullptr, Js::Configuration::Global.flags, PageAllocatorType_BGJIT,
             AutoSystemInfo::Data.IsLowMemoryProcess() ?
             PageAllocator::DefaultLowMaxFreePageCount :
             PageAllocator::DefaultMaxFreePageCount
         ),
    -    processContext(processContext)
    +    processContext(processContext),
    +    m_canCreatePreReservedSegment(data->allowPrereserveAlloc != FALSE)
     {
         m_pid = GetProcessId(processContext->processHandle);
     
    -#if !TARGET_64 && _CONTROL_FLOW_GUARD
    -    m_codeGenAlloc.canCreatePreReservedSegment = data->allowPrereserveAlloc != FALSE;
    -#endif
         m_numericPropertyBV = HeapNew(BVSparse<HeapAllocator>, &HeapAllocator::Instance);
     }
     
    @@ -121,22 +118,16 @@ ServerThreadContext::GetThunkPageAllocators()
         return &m_thunkPageAllocators;
     }
     
    -CustomHeap::OOPCodePageAllocators *
    -ServerThreadContext::GetCodePageAllocators()
    -{
    -    return &m_codePageAllocators;
    -}
    -
     SectionAllocWrapper *
     ServerThreadContext::GetSectionAllocator()
     {
         return &m_sectionAllocator;
     }
     
    -OOPCodeGenAllocators *
    -ServerThreadContext::GetCodeGenAllocators()
    +CustomHeap::OOPCodePageAllocators *
    +ServerThreadContext::GetCodePageAllocators()
     {
    -    return &m_codeGenAlloc;
    +    return &m_codePageAllocators;
     }
     
     #if defined(_CONTROL_FLOW_GUARD) && !defined(_M_ARM)
    @@ -172,6 +163,12 @@ ServerThreadContext::GetForegroundPageAllocator()
         return &m_pageAlloc;
     }
     
    +bool
    +ServerThreadContext::CanCreatePreReservedSegment() const
    +{
    +    return m_canCreatePreReservedSegment;
    +}
    +
     bool
     ServerThreadContext::IsNumericProperty(Js::PropertyId propertyId)
     {
    
  • lib/Backend/ServerThreadContext.h+2 2 modified
    @@ -55,7 +55,6 @@ class ServerThreadContext : public ThreadContextInfo
         virtual ptrdiff_t GetChakraBaseAddressDifference() const override;
         virtual ptrdiff_t GetCRTBaseAddressDifference() const override;
     
    -    OOPCodeGenAllocators * GetCodeGenAllocators();
     #if defined(_CONTROL_FLOW_GUARD) && !defined(_M_ARM)
         OOPJITThunkEmitter * GetJITThunkEmitter();
     #endif
    @@ -72,6 +71,7 @@ class ServerThreadContext : public ThreadContextInfo
     
         intptr_t GetRuntimeChakraBaseAddress() const;
         intptr_t GetRuntimeCRTBaseAddress() const;
    +    bool CanCreatePreReservedSegment() const;
     
         static intptr_t GetJITCRTBaseAddress();
     
    @@ -84,7 +84,6 @@ class ServerThreadContext : public ThreadContextInfo
         SectionAllocWrapper m_sectionAllocator;
         CustomHeap::OOPCodePageAllocators m_thunkPageAllocators;
         CustomHeap::OOPCodePageAllocators  m_codePageAllocators;
    -    OOPCodeGenAllocators m_codeGenAlloc;
     #if defined(_CONTROL_FLOW_GUARD) && !defined(_M_ARM)
         OOPJITThunkEmitter m_jitThunkEmitter;
     #endif
    @@ -96,5 +95,6 @@ class ServerThreadContext : public ThreadContextInfo
     
         CriticalSection m_cs;
         uint m_refCount;
    +    bool m_canCreatePreReservedSegment;
     };
     #endif
    
  • lib/JITClient/JITManager.cpp+2 2 modified
    @@ -586,15 +586,15 @@ JITManager::CloseScriptContext(
     
     HRESULT
     JITManager::FreeAllocation(
    -    __in PTHREADCONTEXT_HANDLE threadContextInfoAddress,
    +    __in PSCRIPTCONTEXT_HANDLE scriptContextInfoAddress,
         __in intptr_t codeAddress)
     {
         Assert(IsOOPJITEnabled());
     
         HRESULT hr = E_FAIL;
         RpcTryExcept
         {
    -        hr = ClientFreeAllocation(m_rpcBindingHandle, threadContextInfoAddress, codeAddress);
    +        hr = ClientFreeAllocation(m_rpcBindingHandle, scriptContextInfoAddress, codeAddress);
         }
         RpcExcept(RpcExceptionFilter(RpcExceptionCode()))
         {
    
  • lib/JITClient/JITManager.h+2 2 modified
    @@ -79,7 +79,7 @@ class JITManager
             __in PSCRIPTCONTEXT_HANDLE scriptContextInfoAddress);
     
         HRESULT FreeAllocation(
    -        __in PTHREADCONTEXT_HANDLE threadContextInfoAddress,
    +        __in PSCRIPTCONTEXT_HANDLE scriptContextInfoAddress,
             __in intptr_t codeAddress);
     
         HRESULT SetIsPRNGSeeded(
    @@ -213,7 +213,7 @@ class JITManager
             { Assert(false); return E_FAIL; }
     
         HRESULT FreeAllocation(
    -        __in PTHREADCONTEXT_HANDLE threadContextInfoAddress,
    +        __in PSCRIPTCONTEXT_HANDLE scriptContextInfoAddress,
             __in intptr_t codeAddress)
             { Assert(false); return E_FAIL; }
     
    
  • lib/JITIDL/ChakraJIT.idl+1 1 modified
    @@ -85,7 +85,7 @@ interface IChakraJIT
     
         HRESULT FreeAllocation(
             [in] handle_t binding,
    -        [in] PTHREADCONTEXT_HANDLE threadContextInfoAddress,
    +        [in] PSCRIPTCONTEXT_HANDLE scriptContextInfoAddress,
             [in] CHAKRA_PTR codeAddress);
     
         HRESULT NewInterpreterThunkBlock(
    
  • lib/JITServer/JITServer.cpp+4 4 modified
    @@ -676,10 +676,10 @@ ServerIsInterpreterThunkAddr(
     HRESULT
     ServerFreeAllocation(
         /* [in] */ handle_t binding,
    -    /* [in] */ __RPC__in PTHREADCONTEXT_HANDLE threadContextInfo,
    +    /* [in] */ __RPC__in PSCRIPTCONTEXT_HANDLE scriptContextInfo,
         /* [in] */ intptr_t codeAddress)
     {
    -    ServerThreadContext * context = (ServerThreadContext*)DecodePointer(threadContextInfo);
    +    ServerScriptContext* context = (ServerScriptContext*)DecodePointer(scriptContextInfo);
     
         if (context == nullptr)
         {
    @@ -709,7 +709,7 @@ ServerIsNativeAddr(
     
         *result = false;
     
    -    ServerThreadContext * context = (ServerThreadContext*)DecodePointer(threadContextInfo);
    +    ServerThreadContext* context = (ServerThreadContext*)DecodePointer(threadContextInfo);
         if (context == nullptr)
         {
             Assert(false);
    @@ -850,7 +850,7 @@ ServerRemoteCodeGen(
                 nullptr,
                 nullptr,
                 jitWorkItem->GetPolymorphicInlineCacheInfo(),
    -            threadContextInfo->GetCodeGenAllocators(),
    +            scriptContextInfo->GetCodeGenAllocators(),
     #if !FLOATVAR
                 nullptr, // number allocator
     #endif
    
  • lib/Runtime/Base/ScriptContext.cpp+7 6 modified
    @@ -701,6 +701,13 @@ namespace Js
             }
     #endif
     
    +#if ENABLE_NATIVE_CODEGEN
    +        if (m_remoteScriptContextAddr)
    +        {
    +            JITManager::GetJITManager()->CloseScriptContext(m_remoteScriptContextAddr);
    +        }
    +#endif
    +
     #ifdef ENABLE_SCRIPT_PROFILING
             // Stop profiling if present
             DeRegisterProfileProbe(S_OK, nullptr);
    @@ -1452,12 +1459,6 @@ namespace Js
     #endif
                 }
     
    -#if ENABLE_NATIVE_CODEGEN
    -            if (m_remoteScriptContextAddr)
    -            {
    -                JITManager::GetJITManager()->CloseScriptContext(m_remoteScriptContextAddr);
    -            }
    -#endif
                 this->PrintStats();
             }
         }
    
  • lib/Runtime/Library/DataView.cpp+1 2 modified
    @@ -597,8 +597,7 @@ namespace Js
             {
                 JavascriptError::ThrowTypeError(scriptContext, JSERR_NeedArrayBufferObject);
             }
    -
    -        return arrayBuffer;
    +        return CrossSite::MarshalVar(scriptContext, arrayBuffer);
         }
     
         Var DataView::EntryGetterByteLength(RecyclableObject* function, CallInfo callInfo, ...)
    
  • lib/Runtime/Library/WebAssemblyInstance.cpp+1 1 modified
    @@ -121,7 +121,7 @@ WebAssemblyInstance::GetterExports(RecyclableObject* function, CallInfo callInfo
             Assert(UNREACHED);
             exports = scriptContext->GetLibrary()->GetUndefined();
         }
    -    return exports;
    +    return CrossSite::MarshalVar(scriptContext, exports);
     }
     
     WebAssemblyInstance *
    
  • lib/Runtime/Library/WebAssemblyMemory.cpp+1 1 modified
    @@ -239,7 +239,7 @@ WebAssemblyMemory::EntryGetterBuffer(RecyclableObject* function, CallInfo callIn
     
         WebAssemblyMemory* memory = WebAssemblyMemory::FromVar(args[0]);
         Assert(ArrayBuffer::Is(memory->m_buffer));
    -    return memory->m_buffer;
    +    return CrossSite::MarshalVar(scriptContext, memory->m_buffer);
     }
     
     WebAssemblyMemory *
    

Vulnerability mechanics

Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

10

News mentions

0

No linked articles in our index yet.