From efddf9894ccf3767f5a3242cfe9e1f14f8d78cc8 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Wed, 14 Oct 2026 22:05:42 +0200 Subject: [PATCH] MDEV-41541 uninitialized memory read in optimizer replay init all frequencies - not all of them might be present in the replay --- .../main/opt_context_load_stats_basic.result | 57 +++++++++++++++++++ .../main/opt_context_load_stats_basic.test | 22 +++++++ sql/opt_context_store_replay.cc | 2 +- 3 files changed, 80 insertions(+), 1 deletion(-) diff --git a/mysql-test/main/opt_context_load_stats_basic.result b/mysql-test/main/opt_context_load_stats_basic.result index 15d1eca01d4..742817c5c17 100644 --- a/mysql-test/main/opt_context_load_stats_basic.result +++ b/mysql-test/main/opt_context_load_stats_basic.result @@ -424,3 +424,60 @@ Warnings: Warning 4269 Failed to parse saved optimizer context: "copy_cost" element not present at offset 631. drop table t1; drop database db1; +use test; +# +# MDEV-41541 uninitialized memory read in optimizer replay +# +create table t1 (a int, b int, index t1_idx_ab (a, b)); +insert into t1 select seq%5, seq%8 from seq_1_to_20; +Warnings: +Warning 4269 Failed to parse saved optimizer context: "copy_cost" element not present at offset 631. +set session use_stat_tables='complementary'; +analyze table t1 persistent for all; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze status Table is already up to date +select a+1, b+1 from t1 limit 5; +a+1 b+1 +1 3 +1 5 +1 6 +1 8 +2 1 +Warnings: +Warning 4269 Failed to parse saved optimizer context: "copy_cost" element not present at offset 631. +select * from t1 where a<2 and b>4; +a b +0 5 +0 7 +1 6 +Warnings: +Warning 4269 Failed to parse saved optimizer context: "copy_cost" element not present at offset 631. +set optimizer_record_context=ON; +select * from t1 where a<3 and b>6; +a b +0 7 +2 7 +Warnings: +Warning 4269 Failed to parse saved optimizer context: "copy_cost" element not present at offset 631. +set @opt_context= +(select REGEXP_SUBSTR( +context, +'(?<=set @opt_context=\')([\n\r].*)*(?=\'\;#opt_context_ends)') +from information_schema.optimizer_context); +set @opt_context_truncated= json_remove(@opt_context, '$.tables[0].indexes[0].rec_per_key[1]'); +set optimizer_replay_context='opt_context_truncated'; +select * from t1 where a<3 and b>6; +a b +0 7 +2 7 +set @opt_context= +(select REGEXP_SUBSTR( +context, +'(?<=set @opt_context=\')([\n\r].*)*(?=\'\;#opt_context_ends)') +from information_schema.optimizer_context); +select hex(json_extract(@opt_context, '$.tables[0].indexes[0].rec_per_key[1]') + 0.0); +hex(json_extract(@opt_context, '$.tables[0].indexes[0].rec_per_key[1]') + 0.0) +0 +drop table t1; +# End of 13.1 tests diff --git a/mysql-test/main/opt_context_load_stats_basic.test b/mysql-test/main/opt_context_load_stats_basic.test index cb80d24e1e2..9306ade28ae 100644 --- a/mysql-test/main/opt_context_load_stats_basic.test +++ b/mysql-test/main/opt_context_load_stats_basic.test @@ -289,3 +289,25 @@ select * from t1 where a > 10; drop table t1; drop database db1; +use test; + +--echo # +--echo # MDEV-41541 uninitialized memory read in optimizer replay +--echo # +create table t1 (a int, b int, index t1_idx_ab (a, b)); +insert into t1 select seq%5, seq%8 from seq_1_to_20; +set session use_stat_tables='complementary'; +analyze table t1 persistent for all; +select a+1, b+1 from t1 limit 5; +select * from t1 where a<2 and b>4; +set optimizer_record_context=ON; +select * from t1 where a<3 and b>6; +--source include/opt_context_save_in_var.inc +set @opt_context_truncated= json_remove(@opt_context, '$.tables[0].indexes[0].rec_per_key[1]'); +set optimizer_replay_context='opt_context_truncated'; +select * from t1 where a<3 and b>6; +--source include/opt_context_save_in_var.inc +select hex(json_extract(@opt_context, '$.tables[0].indexes[0].rec_per_key[1]') + 0.0); +drop table t1; + +--echo # End of 13.1 tests diff --git a/sql/opt_context_store_replay.cc b/sql/opt_context_store_replay.cc index 7adf1eddea7..fe4a8335570 100644 --- a/sql/opt_context_store_replay.cc +++ b/sql/opt_context_store_replay.cc @@ -1939,7 +1939,7 @@ void Optimizer_context_replay::infuse_table_stats(TABLE *table) return; // OOM ulonglong *frequencies= - (ulonglong *) thd->alloc(sizeof(ulonglong) * num_key_parts); + (ulonglong *) thd->calloc(sizeof(ulonglong) * num_key_parts); if (unlikely(!frequencies)) return; // OOM