Please handle via private channel — I am reporting this here as a fallback since Hermes has no SECURITY.md. Meta's security team may reach me via GitHub (@evilgensec) or through the Meta Bug Bounty program.
Summary
Two heap out-of-bounds read vulnerabilities in BCProviderFromBuffer allow a crafted .hbc bytecode file to trigger OOB memory reads during bytecode loading and execution.
Bug 1: Unvalidated getLargeHeaderOffset() (HIGH)
File: include/hermes/BCGen/HBC/BCProvider.h:459, lib/BCGen/HBC/BCProvider.cpp:658, lib/BCGen/HBC/BCProvider.cpp:725
When a SmallFuncHeader has overflowed=true, getLargeHeaderOffset() (a 32-bit attacker-controlled value) is added directly to bufferPtr_ without bounds checking:
// BCProvider.h:458-460 — no bounds check on getLargeHeaderOffset()
auto large = reinterpret_cast<const hbc::FunctionHeader *>(
bufferPtr_ + smallHeader.getLargeHeaderOffset());
return RuntimeFunctionHeader(large);
If getLargeHeaderOffset() > fileLength, large points past the bytecode buffer. All subsequent field reads (e.g., getOffset(), getBytecodeSizeInBytes(), flags) are heap OOB reads.
Downstream impact: getBytecode(functionID) at BCProvider.h:495 returns bufferPtr_ + [OOB-read offset], causing the interpreter/JIT to execute arbitrary heap data as bytecode instructions.
Bug 2: Unvalidated overflow string table index (MEDIUM)
File: include/hermes/BCGen/HBC/BCProvider.h:482
When a SmallStringTableEntry has isOverflowed()=true, getOffset() (up to 23 bits, attacker-controlled) is used as an index into overflowStringTableEntries_ without validation against overflowStringCount:
// BCProvider.h:481-482 — getOffset() not bounded by overflowStringCount
if (LLVM_UNLIKELY(smallHeader.isOverflowed())) {
auto overflow = overflowStringTableEntries_[smallHeader.getOffset()]; // OOB
llvh::ArrayRef::operator[] performs no bounds checking. The returned OOB data is used as an offset+length to construct a StringRef pointing to arbitrary memory.
Attack Surface
- React Native apps with OTA updates (e.g., CodePush) loading
.hbc bundles
- Any app loading bytecode from external/untrusted sources
- MITM on OTA update channel → craft malicious
.hbc → OOB reads in user device
Suggested Fix
Validate getLargeHeaderOffset() against fileLength - sizeof(FunctionHeader) before use. Validate smallHeader.getOffset() against overflowStringTableEntries_.size() before indexing.
Reported by evilgensec. Full technical details available privately.
Please handle via private channel — I am reporting this here as a fallback since Hermes has no SECURITY.md. Meta's security team may reach me via GitHub (@evilgensec) or through the Meta Bug Bounty program.
Summary
Two heap out-of-bounds read vulnerabilities in
BCProviderFromBufferallow a crafted.hbcbytecode file to trigger OOB memory reads during bytecode loading and execution.Bug 1: Unvalidated
getLargeHeaderOffset()(HIGH)File:
include/hermes/BCGen/HBC/BCProvider.h:459,lib/BCGen/HBC/BCProvider.cpp:658,lib/BCGen/HBC/BCProvider.cpp:725When a
SmallFuncHeaderhasoverflowed=true,getLargeHeaderOffset()(a 32-bit attacker-controlled value) is added directly tobufferPtr_without bounds checking:If
getLargeHeaderOffset() > fileLength,largepoints past the bytecode buffer. All subsequent field reads (e.g.,getOffset(),getBytecodeSizeInBytes(),flags) are heap OOB reads.Downstream impact:
getBytecode(functionID)at BCProvider.h:495 returnsbufferPtr_ + [OOB-read offset], causing the interpreter/JIT to execute arbitrary heap data as bytecode instructions.Bug 2: Unvalidated overflow string table index (MEDIUM)
File:
include/hermes/BCGen/HBC/BCProvider.h:482When a
SmallStringTableEntryhasisOverflowed()=true,getOffset()(up to 23 bits, attacker-controlled) is used as an index intooverflowStringTableEntries_without validation againstoverflowStringCount:llvh::ArrayRef::operator[]performs no bounds checking. The returned OOB data is used as anoffset+lengthto construct aStringRefpointing to arbitrary memory.Attack Surface
.hbcbundles.hbc→ OOB reads in user deviceSuggested Fix
Validate
getLargeHeaderOffset()againstfileLength - sizeof(FunctionHeader)before use. ValidatesmallHeader.getOffset()againstoverflowStringTableEntries_.size()before indexing.Reported by evilgensec. Full technical details available privately.