[MDEV-33052] MSAN use-of-uninitialized-value in buf_read_ahead_linear() Created: 2023-12-18  Updated: 2023-12-18  Resolved: 2023-12-18

Status: Closed
Project: MariaDB Server
Component/s: Storage Engine - InnoDB
Affects Version/s: 10.5, 10.6, 10.7, 10.8, 10.9, 10.10, 10.11, 11.0, 11.1, 11.2, 11.3
Fix Version/s: 10.5.24, 10.6.17, 10.11.7, 11.0.5, 11.1.4, 11.2.3, 11.3.2

Type: Bug Priority: Major
Reporter: Marko Mäkelä Assignee: Marko Mäkelä
Resolution: Fixed Votes: 0
Labels: MSAN


 Description   

The following failure was observed for a 10.6 based MemorySanitizer instrumented build:

CURRENT_TEST: innodb_fts.bug_32831765
mysqltest: At line 132: query 'call proc_insert('t4')' failed: <Unknown> (2013): Lost connection to server during query
==144078==WARNING: MemorySanitizer: use-of-uninitialized-value
2023-12-14 13:49:23 0 [Warning] InnoDB: Total InnoDB FTS size 12042992 for the table `test`.`t1` exceeds the innodb_ft_cache_size 8000000
    #0 0x5631e352a167 in buf_read_ahead_linear(page_id_t, unsigned long, bool) /home/buildbot/amd64-debian-11-msan/build/storage/innobase/buf/buf0rea.cc:600:28
    #1 0x5631e5e6cd22 in btr_cur_t::search_leaf(dtuple_t const*, page_cur_mode_t, btr_latch_mode, mtr_t*) /home/buildbot/amd64-debian-11-msan/build/storage/innobase/btr/btr0cur.cc:1588:9
    #2 0x5631e5ee5ac1 in btr_pcur_open_with_no_init(dtuple_t const*, page_cur_mode_t, btr_latch_mode, btr_pcur_t*, mtr_t*) /home/buildbot/amd64-debian-11-msan/build/storage/innobase/include/btr0pcur.inl:322:26
    #3 0x5631e5ee5ac1 in btr_pcur_t::restore_position(btr_latch_mode, mtr_t*) /home/buildbot/amd64-debian-11-msan/build/storage/innobase/btr/btr0pcur.cc:461:6
    #4 0x5631e61b9877 in fts_add_doc_by_id(fts_trx_table_t*, unsigned long) /home/buildbot/amd64-debian-11-msan/build/storage/innobase/fts/fts0fts.cc:3547:20
    #5 0x5631e61b9877 in fts_add(fts_trx_table_t*, fts_trx_row_t*) /home/buildbot/amd64-debian-11-msan/build/storage/innobase/fts/fts0fts.cc:2797:2
    #6 0x5631e61bce98 in fts_commit_table(fts_trx_table_t*) /home/buildbot/amd64-debian-11-msan/build/storage/innobase/fts/fts0fts.cc:2959:4
    #7 0x5631e61bce98 in fts_commit(trx_t*) /home/buildbot/amd64-debian-11-msan/build/storage/innobase/fts/fts0fts.cc:3008:11
    #8 0x5631e35031c3 in trx_t::commit_low(mtr_t*) /home/buildbot/amd64-debian-11-msan/build/storage/innobase/trx/trx0trx.cc:1536:30
    #9 0x5631e5d9e72f in trx_t::commit_persist() /home/buildbot/amd64-debian-11-msan/build/storage/innobase/trx/trx0trx.cc:1588:3
    #10 0x5631e5d9e72f in trx_t::commit() /home/buildbot/amd64-debian-11-msan/build/storage/innobase/trx/trx0trx.cc:1597:3
    #11 0x5631e5da1298 in trx_commit_for_mysql(trx_t*) /home/buildbot/amd64-debian-11-msan/build/storage/innobase/trx/trx0trx.cc:1714:8
    #12 0x5631e5632d20 in innobase_commit_low(trx_t*) /home/buildbot/amd64-debian-11-msan/build/storage/innobase/handler/ha_innodb.cc:4394:3
    #13 0x5631e5632d20 in innobase_commit_ordered_2(trx_t*, THD*) /home/buildbot/amd64-debian-11-msan/build/storage/innobase/handler/ha_innodb.cc:4498:2
    #14 0x5631e56182fa in innobase_commit(handlerton*, THD*, bool) /home/buildbot/amd64-debian-11-msan/build/storage/innobase/handler/ha_innodb.cc:4599:4
    #15 0x5631e465240a in commit_one_phase_2(THD*, bool, THD_TRANS*, bool) /home/buildbot/amd64-debian-11-msan/build/sql/handler.cc:2099:17
    #16 0x5631e4653cc1 in ha_commit_one_phase(THD*, bool) /home/buildbot/amd64-debian-11-msan/build/sql/handler.cc:2052:8
    #17 0x5631e464e22d in ha_commit_trans(THD*, bool) /home/buildbot/amd64-debian-11-msan/build/sql/handler.cc:1846:12
    #18 0x5631e4061211 in trans_commit_stmt(THD*) /home/buildbot/amd64-debian-11-msan/build/sql/transaction.cc:472:10
    #19 0x5631e3a3fabc in mysql_execute_command(THD*, bool) /home/buildbot/amd64-debian-11-msan/build/sql/sql_parse.cc:6086:7

As far as I can tell, this can be expected, and we should silence the error as follows:

diff --git a/storage/innobase/buf/buf0rea.cc b/storage/innobase/buf/buf0rea.cc
index c81017bb024..26bfb7eb0fc 100644
--- a/storage/innobase/buf/buf0rea.cc
+++ b/storage/innobase/buf/buf0rea.cc
@@ -643,6 +643,12 @@ buf_read_ahead_linear(const page_id_t page_id, ulint zip_size, bool ibuf)
 
       uint32_t prev= mach_read_from_4(my_assume_aligned<4>(f + FIL_PAGE_PREV));
       uint32_t next= mach_read_from_4(my_assume_aligned<4>(f + FIL_PAGE_NEXT));
+      /* The underlying file page of this buffer pool page could actually
+      be marked as freed, or a read of the page into the buffer pool might
+      be in progress. We may read uninitialized data here.
+      Suppress warnings of comparing uninitialized values. */
+      MEM_MAKE_DEFINED(&prev, sizeof prev);
+      MEM_MAKE_DEFINED(&next, sizeof next);
       if (prev == FIL_NULL || next == FIL_NULL)
         goto hard_fail;
       page_id_t id= page_id;

This is an unsafe access of some page header fields. If the fields are not as expected, then linear read-ahead may not be attempted. So, this comparison of potentially uninitialized data only is causing some potential performance impact, no correctness issue.


Generated at Thu Feb 08 10:36:01 UTC 2024 using Jira 8.20.16#820016-sha1:9d11dbea5f4be3d4cc21f03a88dd11d8c8687422.