[bug] Fix bound BitVectorRangeIterator range_start to _end in JitAllocator#523
Open
puzpuzpuz wants to merge 1 commit into
Open
[bug] Fix bound BitVectorRangeIterator range_start to _end in JitAllocator#523puzpuzpuz wants to merge 1 commit into
puzpuzpuz wants to merge 1 commit into
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
BitVectorRangeIterator::next_range()did not clamp*range_startagainst_end. The iterator'sinit()only masks bits before start, so the underlyingBitWordcan carry free bits past end. Whenctzpicked such a bit, the caller would computerange_size = range_end - range_startassize_t(range_endgets clamped to_end), the subtraction would underflow to a huge value, and a range that lies entirely past the search region would be accepted.Inside
JitAllocator::allocthis produced anarea_indexoutside the block: the returnedSpanreported its requested size even though the underlying memory ran past the block boundary into unmapped pages. QuestDB caught this as a SIGSEGV insideJitRuntime::_add's memcpy: a production core dump shows a block with _area_size=4096, _search_end=4083 and 3 free bits at the tail (areas 4093-4095). A 7-area request let the iterator pick range_start=4093 with range_end clamped to 4083, _area_used over-incremented by 4, the Span claimed 448 bytes when only 192 were valid, and the JIT runtime memcpy walked off the end of the block.The fix adds a single bound check:
if *range_start >= _endafter thectz, the iterator reports end-of-iteration. Two regression tests cover the path:test_bit_vector_range_iterator_bounds()exercises the iterator directly with two hand-crafted bitmaps (same-word and multi-word search regions). Without the fixEXPECT_LT(range_start, end)fails on the first iterator call.test_jit_allocator_search_end_bounds()drivesJitAllocatorinto the production state (area_used = area_size - 14, free bits both inside the search range and at the tail past _search_end). With the bug the alloc trips the existing offset <= block_size - size assertion at line ~999; with the fix the search reports no fit and a fresh block is allocated.