Skip to content

Commit 4be442e

Browse files
Thirunarayanangrooverdan
authored andcommitted
MDEV-36962 innodb.log_file_overwrite fails with ASAN
Problem: ======= - InnoDB unpoisons the freed page memory to make sure that no other thread uses this freed page. In buf_pool_t::close(), InnoDB unmap() the buffer pool memory during shutdown or it encountered during startup. Later at some point, server re-uses the same virtual address using mmap() and writes into memory region. This leads to use_after_poison error. This issue doesn't happen in latest clang and gcc version. Older version of clang and gcc can still fail with this error. ASAN should unpoison the memory while reusing the same virtual address. This issue was already raised in google/sanitizers#1705 Fix: === In order to avoid this failure, let's unpoison the buffer pool memory explictly during buf_pool_t::close() for lesser than gcc-14 and clang-18 version.
1 parent 39ef6c0 commit 4be442e

File tree

1 file changed

+21
-0
lines changed

1 file changed

+21
-0
lines changed

storage/innobase/buf/buf0buf.cc

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1514,6 +1514,27 @@ void buf_pool_t::close() noexcept
15141514
{
15151515
const size_t size{size_in_bytes};
15161516

1517+
#ifdef __SANITIZE_ADDRESS__
1518+
/* Sequence of operation which leads to use_after_poison error:
1519+
1520+
mmap();
1521+
__asan_poison_memory_region();
1522+
munmap();
1523+
mmap() reuses the same virtual address
1524+
Write into the memory region throws the error.
1525+
1526+
Recent clang-18, gcc-13.3 doesn't detect this error.
1527+
Older like clang-14..clang-16 and gcc-10, gcc-11, gcc-12 detects
1528+
this error. Please check the reported bug
1529+
(https://github.com/google/sanitizers/issues/1705)
1530+
1531+
Unpoison the whole buffer pool memory to avoid this error */
1532+
#if (defined(__GNUC__) && !defined(__clang__) && (__GNUC__ < 14)) ||\
1533+
(defined(__clang__) && (__clang_major__ < 18))
1534+
MEM_MAKE_ADDRESSABLE(memory, size);
1535+
#endif /* __GNUC__ __clang */
1536+
#endif /* __SANITIZE_ADDRESS__ */
1537+
15171538
for (char *extent= memory,
15181539
*end= memory + block_descriptors_in_bytes(n_blocks);
15191540
extent < end; extent+= innodb_buffer_pool_extent_size)

0 commit comments

Comments
 (0)