AK: Fix BumpAllocator iteration if last object doesn't align

This fixes two bugs:

1. `end_offset` was missing the alignment that might have been
   introduced while computing `base_ptr`.
2. Ignoring point 1, `end_offset` computed the offset of the first byte
   that is outside the current chunk. However, this might be in the
   middle of a (hypothetical) object! The loop treats `end_offset` as if
   it points to the first byte beyond the last (valid) object. So if the
   last few bytes of the chunk are unused, the loop iterates once too
   often.

Found by OSS Fuzz, long-standing issue (since 2021-07-31)
https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=38733
(This probably also resolves some other issues that go through
RegexMatcher.)

See also: 0f1425c895
This commit is contained in:
Ben Wiederhake 2021-10-22 20:08:44 +02:00 committed by Linus Groh
parent 885b69c877
commit 5d865d574a

View file

@ -175,7 +175,10 @@ public:
{
this->for_each_chunk([&](auto chunk) {
auto base_ptr = align_up_to(chunk + sizeof(typename Allocator::ChunkHeader), alignof(T));
FlatPtr end_offset = this->m_chunk_size - sizeof(typename Allocator::ChunkHeader);
// Compute the offset of the first byte *after* this chunk:
FlatPtr end_offset = base_ptr + this->m_chunk_size - chunk;
// Compute the offset of the first byte *after* the last valid object, in case the end of the chunk does not align with the end of an object:
end_offset = (end_offset / sizeof(T)) * sizeof(T);
if (chunk == this->m_current_chunk)
end_offset = this->m_byte_offset_into_current_chunk;
for (; base_ptr - chunk < end_offset; base_ptr += sizeof(T))