Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[CVE-2018-0818] Add ProcessContexts for OOP JIT #4427

Merged
merged 2 commits into from
Dec 15, 2017
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
55 changes: 41 additions & 14 deletions lib/Backend/ServerThreadContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,27 +8,26 @@
#if ENABLE_OOP_NATIVE_CODEGEN
#include "JITServer/JITServer.h"

ServerThreadContext::ServerThreadContext(ThreadContextDataIDL * data, HANDLE processHandle) :
m_autoProcessHandle(processHandle),
m_processHandle(processHandle),
ServerThreadContext::ServerThreadContext(ThreadContextDataIDL* data, ProcessContext* processContext) :
m_threadContextData(*data),
m_refCount(0),
m_numericPropertyBV(nullptr),
m_preReservedSectionAllocator(processHandle),
m_sectionAllocator(processHandle),
m_thunkPageAllocators(nullptr, /* allocXData */ false, &m_sectionAllocator, nullptr, processHandle),
m_codePageAllocators(nullptr, ALLOC_XDATA, &m_sectionAllocator, &m_preReservedSectionAllocator, processHandle),
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),
#if defined(_CONTROL_FLOW_GUARD) && !defined(_M_ARM)
m_jitThunkEmitter(this, &m_sectionAllocator, processHandle),
m_jitThunkEmitter(this, &m_sectionAllocator, processContext->processHandle),
#endif
m_codeGenAlloc(nullptr, nullptr, this, &m_codePageAllocators, processHandle),
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)
{
m_pid = GetProcessId(processHandle);
m_pid = GetProcessId(processContext->processHandle);

#if !TARGET_64 && _CONTROL_FLOW_GUARD
m_codeGenAlloc.canCreatePreReservedSegment = data->allowPrereserveAlloc != FALSE;
Expand All @@ -38,6 +37,7 @@ ServerThreadContext::ServerThreadContext(ThreadContextDataIDL * data, HANDLE pro

ServerThreadContext::~ServerThreadContext()
{
processContext->Release();
if (this->m_numericPropertyBV != nullptr)
{
HeapDelete(m_numericPropertyBV);
Expand Down Expand Up @@ -112,7 +112,7 @@ ServerThreadContext::IsThreadBound() const
HANDLE
ServerThreadContext::GetProcessHandle() const
{
return m_autoProcessHandle.GetHandle();
return this->processContext->processHandle;
}

CustomHeap::OOPCodePageAllocators *
Expand Down Expand Up @@ -150,13 +150,13 @@ ServerThreadContext::GetJITThunkEmitter()
intptr_t
ServerThreadContext::GetRuntimeChakraBaseAddress() const
{
return static_cast<intptr_t>(m_threadContextData.chakraBaseAddress);
return this->processContext->chakraBaseAddress;
}

intptr_t
ServerThreadContext::GetRuntimeCRTBaseAddress() const
{
return static_cast<intptr_t>(m_threadContextData.crtBaseAddress);
return this->processContext->crtBaseAddress;
}

/* static */
Expand Down Expand Up @@ -215,4 +215,31 @@ void ServerThreadContext::Close()
ServerContextManager::RecordCloseContext(this);
#endif
}

ProcessContext::ProcessContext(HANDLE processHandle, intptr_t chakraBaseAddress, intptr_t crtBaseAddress) :
processHandle(processHandle),
chakraBaseAddress(chakraBaseAddress),
crtBaseAddress(crtBaseAddress),
refCount(0)
{
}
ProcessContext::~ProcessContext()
{
CloseHandle(processHandle);
}

void ProcessContext::AddRef()
{
InterlockedExchangeAdd(&this->refCount, 1);
}
void ProcessContext::Release()
{
InterlockedExchangeSubtract(&this->refCount, 1);
}

bool ProcessContext::HasRef()
{
return this->refCount != 0;
}

#endif
27 changes: 22 additions & 5 deletions lib/Backend/ServerThreadContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,31 @@

#pragma once

#if ENABLE_OOP_NATIVE_CODEGEN
class ProcessContext
{
private:
uint refCount;

public:
HANDLE processHandle;
intptr_t chakraBaseAddress;
intptr_t crtBaseAddress;

ProcessContext(HANDLE processHandle, intptr_t chakraBaseAddress, intptr_t crtBaseAddress);
~ProcessContext();
void AddRef();
void Release();
bool HasRef();

};

class ServerThreadContext : public ThreadContextInfo
{
#if ENABLE_OOP_NATIVE_CODEGEN
public:
typedef BVSparseNode<JitArenaAllocator> BVSparseNode;

ServerThreadContext(ThreadContextDataIDL * data, HANDLE processHandle);
ServerThreadContext(ThreadContextDataIDL * data, ProcessContext* processContext);
~ServerThreadContext();

virtual HANDLE GetProcessHandle() const override;
Expand Down Expand Up @@ -58,7 +76,7 @@ class ServerThreadContext : public ThreadContextInfo
static intptr_t GetJITCRTBaseAddress();

private:
AutoCloseHandle m_autoProcessHandle;
ProcessContext* processContext;

BVSparse<HeapAllocator> * m_numericPropertyBV;

Expand All @@ -72,12 +90,11 @@ class ServerThreadContext : public ThreadContextInfo
#endif
// only allocate with this from foreground calls (never from CodeGen calls)
PageAllocator m_pageAlloc;
HANDLE m_processHandle;
ThreadContextDataIDL m_threadContextData;

DWORD m_pid; //save client process id for easier diagnose

CriticalSection m_cs;
uint m_refCount;
#endif
};
#endif
46 changes: 40 additions & 6 deletions lib/JITClient/JITManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,9 @@ JITManager::ConnectRpcServer(__in HANDLE jitProcessHandle, __in_opt void* server

m_jitConnectionId = connectionUuid;

hr = ConnectProcess();
HandleServerCallResult(hr, RemoteCallType::StateUpdate);

return hr;

FailureCleanup:
Expand Down Expand Up @@ -286,11 +289,45 @@ JITManager::Shutdown()
}

HRESULT
JITManager::InitializeThreadContext(
__in ThreadContextDataIDL * data,
JITManager::ConnectProcess()
{
Assert(IsOOPJITEnabled());

#ifdef USE_RPC_HANDLE_MARSHALLING
HANDLE processHandle;
if (!DuplicateHandle(GetCurrentProcess(), GetCurrentProcess(), GetCurrentProcess(), &processHandle, 0, false, DUPLICATE_SAME_ACCESS))
{
return false;
}
#endif

HRESULT hr = E_FAIL;
RpcTryExcept
{
hr = ClientConnectProcess(
m_rpcBindingHandle,
#ifdef USE_RPC_HANDLE_MARSHALLING
__in HANDLE processHandle,
processHandle,
#endif
(intptr_t)AutoSystemInfo::Data.GetChakraBaseAddr(),
(intptr_t)AutoSystemInfo::Data.GetCRTHandle());
}
RpcExcept(RpcExceptionFilter(RpcExceptionCode()))
{
hr = HRESULT_FROM_WIN32(RpcExceptionCode());
}
RpcEndExcept;

#ifdef USE_RPC_HANDLE_MARSHALLING
CloseHandle(processHandle);
#endif

return hr;
}

HRESULT
JITManager::InitializeThreadContext(
__in ThreadContextDataIDL * data,
__out PPTHREADCONTEXT_HANDLE threadContextInfoAddress,
__out intptr_t * prereservedRegionAddr,
__out intptr_t * jitThunkAddr)
Expand All @@ -303,9 +340,6 @@ JITManager::InitializeThreadContext(
hr = ClientInitializeThreadContext(
m_rpcBindingHandle,
data,
#ifdef USE_RPC_HANDLE_MARSHALLING
processHandle,
#endif
threadContextInfoAddress,
prereservedRegionAddr,
jitThunkAddr);
Expand Down
8 changes: 2 additions & 6 deletions lib/JITClient/JITManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,6 @@ class JITManager

HRESULT InitializeThreadContext(
__in ThreadContextDataIDL * data,
#ifdef USE_RPC_HANDLE_MARSHALLING
__in HANDLE processHandle,
#endif
__out PPTHREADCONTEXT_HANDLE threadContextInfoAddress,
__out intptr_t * prereservedRegionAddr,
__out intptr_t * jitThunkAddr);
Expand Down Expand Up @@ -122,6 +119,8 @@ class JITManager
__in UUID* connectionUuid,
__out RPC_BINDING_HANDLE* bindingHandle);

HRESULT ConnectProcess();

RPC_BINDING_HANDLE m_rpcBindingHandle;
UUID m_jitConnectionId;
bool m_oopJitEnabled;
Expand All @@ -148,9 +147,6 @@ class JITManager

HRESULT InitializeThreadContext(
__in ThreadContextDataIDL * data,
#ifdef USE_RPC_HANDLE_MARSHALLING
__in HANDLE processHandle,
#endif
__out PPTHREADCONTEXT_HANDLE threadContextInfoAddress,
__out intptr_t *prereservedRegionAddr,
__out intptr_t * jitThunkAddr)
Expand Down
11 changes: 9 additions & 2 deletions lib/JITIDL/ChakraJIT.idl
Original file line number Diff line number Diff line change
Expand Up @@ -25,16 +25,23 @@ interface IChakraJIT
{
HRESULT Shutdown([in] handle_t binding);

HRESULT InitializeThreadContext(
HRESULT ConnectProcess(
[in] handle_t binding,
[in] ThreadContextDataIDL * threadData,
#ifdef USE_RPC_HANDLE_MARSHALLING
[in, system_handle(sh_process, PROCESS_VM_OPERATION | PROCESS_VM_READ | PROCESS_VM_WRITE | PROCESS_QUERY_LIMITED_INFORMATION)] HANDLE processHandle,
#endif
[in] CHAKRA_PTR chakraBaseAddress,
[in] CHAKRA_PTR crtBaseAddress
);

HRESULT InitializeThreadContext(
[in] handle_t binding,
[in] ThreadContextDataIDL * threadData,
[out] PPTHREADCONTEXT_HANDLE threadContextInfoAddress,
[out] CHAKRA_PTR * prereservedRegionAddr,
[out] CHAKRA_PTR * jitThunkAddr);


HRESULT CleanupThreadContext(
[in] handle_t binding,
[in, out] PPTHREADCONTEXT_HANDLE threadContextInfoAddress);
Expand Down
2 changes: 0 additions & 2 deletions lib/JITIDL/JITTypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -314,8 +314,6 @@ typedef struct ThreadContextDataIDL

IDL_PAD2(0)
X64_PAD4(1)
CHAKRA_PTR chakraBaseAddress;
CHAKRA_PTR crtBaseAddress;
CHAKRA_PTR threadStackLimitAddr;
CHAKRA_PTR scriptStackLimit;
CHAKRA_PTR bailOutRegisterSaveSpaceAddr;
Expand Down