From 5d865d574a102501bd8a616f01e52e489ce88e6d Mon Sep 17 00:00:00 2001 From: Ben Wiederhake Date: Fri, 22 Oct 2021 20:08:44 +0200 Subject: [PATCH] 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: 0f1425c895ace40fbb10d68a55eeb3a6354479d3 --- AK/BumpAllocator.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/AK/BumpAllocator.h b/AK/BumpAllocator.h index 2bf90dbf24..bce07c4fae 100644 --- a/AK/BumpAllocator.h +++ b/AK/BumpAllocator.h @@ -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))