Skip to content

Commit 67d9af1

Browse files
committed
Bug#35635853 shutdown plugin core when init_events_waits_history_long failed
Problem ======= In some edge cases, when an out of memory condition happens during the performance schema initialization, the server later crashes on cleanup. Root cause ========== The problem is with the internal representation of an array, in the performance schema data buffers. Conceptually, arrays are like a std::span<T> in C++, but the code pre dates C++20 by more than 10 years. For various data types T, the performance schema represents internally an array of T with: - a xxx_array_ptr variable, of type T* - a xxx_array_size variable When an array is not allocated: - xxx_array_ptr == nullptr - xxx_array_size == 0 When an array is allocated: - xxx_array_ptr != nullptr - xxx_array_size != 0 The problem is that on some error path, typically when an allocation fails, the code can leave an inconsistent state, such as: - xxx_array_ptr == nullptr - xxx_array_size != 0 which later confuses code and causes a crash. The same inconsistent state can also exist after cleanup, when the array size is not always reset. Fix === Revised every use of: - PFS_MALLOC_ARRAY, - PFS_FREE_ARRAY, to make sure that the array pointer and the array size are coherent (either both set, or both nullptr / 0). Change-Id: I581a385fc1dc3ee4c2ad516664de6d256649954c
1 parent b11b0e0 commit 67d9af1

File tree

7 files changed

+46
-3
lines changed

7 files changed

+46
-3
lines changed

storage/perfschema/pfs_digest.cc

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,10 @@ int init_digest(const PFS_global_param *param) {
8080
digest_monotonic_index.m_u32.store(1);
8181
digest_full = false;
8282

83+
statements_digest_stat_array = nullptr;
84+
statements_digest_token_array = nullptr;
85+
statements_digest_query_sample_text_array = nullptr;
86+
8387
if (digest_max == 0) {
8488
return 0;
8589
}
@@ -152,6 +156,7 @@ void cleanup_digest() {
152156
statements_digest_stat_array = nullptr;
153157
statements_digest_token_array = nullptr;
154158
statements_digest_query_sample_text_array = nullptr;
159+
digest_max = 0;
155160
}
156161

157162
static const uchar *digest_hash_get_key(const uchar *entry, size_t *length) {

storage/perfschema/pfs_events_stages.cc

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,14 +69,20 @@ int init_events_stages_history_long(uint events_stages_history_long_sizing) {
6969
events_stages_history_long_index.m_u32.store(0);
7070

7171
if (events_stages_history_long_size == 0) {
72+
events_stages_history_long_array = nullptr;
7273
return 0;
7374
}
7475

7576
events_stages_history_long_array = PFS_MALLOC_ARRAY(
7677
&builtin_memory_stages_history_long, events_stages_history_long_size,
7778
sizeof(PFS_events_stages), PFS_events_stages, MYF(MY_ZEROFILL));
7879

79-
return (events_stages_history_long_array ? 0 : 1);
80+
if (events_stages_history_long_array == nullptr) {
81+
events_stages_history_long_size = 0;
82+
return 1;
83+
}
84+
85+
return 0;
8086
}
8187

8288
/** Cleanup table EVENTS_STAGES_HISTORY_LONG. */
@@ -85,6 +91,7 @@ void cleanup_events_stages_history_long() {
8591
events_stages_history_long_size, sizeof(PFS_events_stages),
8692
events_stages_history_long_array);
8793
events_stages_history_long_array = nullptr;
94+
events_stages_history_long_size = 0;
8895
}
8996

9097
static inline void copy_events_stages(PFS_events_stages *dest,

storage/perfschema/pfs_events_statements.cc

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,10 @@ int init_events_statements_history_long(
7474
events_statements_history_long_full = false;
7575
events_statements_history_long_index.m_u32.store(0);
7676

77+
events_statements_history_long_array = nullptr;
78+
h_long_stmts_digest_token_array = nullptr;
79+
h_long_stmts_text_array = nullptr;
80+
7781
if (events_statements_history_long_size == 0) {
7882
return 0;
7983
}
@@ -149,6 +153,7 @@ void cleanup_events_statements_history_long() {
149153
events_statements_history_long_array = nullptr;
150154
h_long_stmts_digest_token_array = nullptr;
151155
h_long_stmts_text_array = nullptr;
156+
events_statements_history_long_size = 0;
152157
}
153158

154159
static inline void copy_events_statements(PFS_events_statements *dest,

storage/perfschema/pfs_events_transactions.cc

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ int init_events_transactions_history_long(
7575
events_transactions_history_long_index.m_u32.store(0);
7676

7777
if (events_transactions_history_long_size == 0) {
78+
events_transactions_history_long_array = nullptr;
7879
return 0;
7980
}
8081

@@ -83,7 +84,12 @@ int init_events_transactions_history_long(
8384
events_transactions_history_long_size, sizeof(PFS_events_transactions),
8485
PFS_events_transactions, MYF(MY_ZEROFILL));
8586

86-
return (events_transactions_history_long_array ? 0 : 1);
87+
if (events_transactions_history_long_array == nullptr) {
88+
events_transactions_history_long_size = 0;
89+
return 1;
90+
}
91+
92+
return 0;
8793
}
8894

8995
/** Cleanup table EVENTS_TRANSACTIONS_HISTORY_LONG. */
@@ -93,6 +99,7 @@ void cleanup_events_transactions_history_long() {
9399
sizeof(PFS_events_transactions),
94100
events_transactions_history_long_array);
95101
events_transactions_history_long_array = nullptr;
102+
events_transactions_history_long_size = 0;
96103
}
97104

98105
static inline void copy_events_transactions(

storage/perfschema/pfs_events_waits.cc

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,14 +70,20 @@ int init_events_waits_history_long(uint events_waits_history_long_sizing) {
7070
events_waits_history_long_index.m_u32.store(0);
7171

7272
if (events_waits_history_long_size == 0) {
73+
events_waits_history_long_array = nullptr;
7374
return 0;
7475
}
7576

7677
events_waits_history_long_array = PFS_MALLOC_ARRAY(
7778
&builtin_memory_waits_history_long, events_waits_history_long_size,
7879
sizeof(PFS_events_waits), PFS_events_waits, MYF(MY_ZEROFILL));
7980

80-
return (events_waits_history_long_array ? 0 : 1);
81+
if (events_waits_history_long_array == nullptr) {
82+
events_waits_history_long_size = 0;
83+
return 1;
84+
}
85+
86+
return 0;
8187
}
8288

8389
/** Cleanup table EVENTS_WAITS_HISTORY_LONG. */
@@ -86,6 +92,7 @@ void cleanup_events_waits_history_long() {
8692
events_waits_history_long_size, sizeof(PFS_events_waits),
8793
events_waits_history_long_array);
8894
events_waits_history_long_array = nullptr;
95+
events_waits_history_long_size = 0;
8996
}
9097

9198
static inline void copy_events_waits(PFS_events_waits *dest,

storage/perfschema/pfs_instr.cc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,7 @@ int init_instruments(const PFS_global_param *param) {
162162
PFS_MALLOC_ARRAY(&builtin_memory_file_handle, file_handle_max,
163163
sizeof(PFS_file *), PFS_file *, MYF(MY_ZEROFILL));
164164
if (unlikely(file_handle_array == nullptr)) {
165+
file_handle_max = 0;
165166
return 1;
166167
}
167168
}

storage/perfschema/pfs_instr_class.cc

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -375,6 +375,7 @@ int init_sync_class(uint mutex_class_sizing, uint rwlock_class_sizing,
375375
&builtin_memory_mutex_class, mutex_class_max, sizeof(PFS_mutex_class),
376376
PFS_mutex_class, MYF(MY_ZEROFILL));
377377
if (unlikely(mutex_class_array == nullptr)) {
378+
mutex_class_max = 0;
378379
return 1;
379380
}
380381
}
@@ -384,6 +385,7 @@ int init_sync_class(uint mutex_class_sizing, uint rwlock_class_sizing,
384385
&builtin_memory_rwlock_class, rwlock_class_max,
385386
sizeof(PFS_rwlock_class), PFS_rwlock_class, MYF(MY_ZEROFILL));
386387
if (unlikely(rwlock_class_array == nullptr)) {
388+
rwlock_class_max = 0;
387389
return 1;
388390
}
389391
}
@@ -393,6 +395,7 @@ int init_sync_class(uint mutex_class_sizing, uint rwlock_class_sizing,
393395
cond_class_max, sizeof(PFS_cond_class),
394396
PFS_cond_class, MYF(MY_ZEROFILL));
395397
if (unlikely(cond_class_array == nullptr)) {
398+
cond_class_max = 0;
396399
return 1;
397400
}
398401
}
@@ -455,6 +458,7 @@ int init_thread_class(uint thread_class_sizing) {
455458
&builtin_memory_thread_class, thread_class_max,
456459
sizeof(PFS_thread_class), PFS_thread_class, MYF(MY_ZEROFILL));
457460
if (unlikely(thread_class_array == nullptr)) {
461+
thread_class_max = 0;
458462
result = 1;
459463
}
460464
} else {
@@ -510,6 +514,7 @@ int init_meter_class(uint meter_class_sizing) {
510514
&builtin_memory_meter_class, meter_class_max, sizeof(PFS_meter_class),
511515
PFS_meter_class, MYF(MY_ZEROFILL));
512516
if (unlikely(meter_class_array == nullptr)) {
517+
meter_class_max = 0;
513518
result = 1;
514519
}
515520
} else {
@@ -556,6 +561,7 @@ int init_metric_class(uint metric_class_sizing) {
556561
&builtin_memory_metric_class, metric_class_max,
557562
sizeof(PFS_metric_class), PFS_metric_class, MYF(MY_ZEROFILL));
558563
if (unlikely(metric_class_array == nullptr)) {
564+
metric_class_max = 0;
559565
result = 1;
560566
}
561567
} else {
@@ -939,6 +945,7 @@ int init_file_class(uint file_class_sizing) {
939945
file_class_max, sizeof(PFS_file_class),
940946
PFS_file_class, MYF(MY_ZEROFILL));
941947
if (unlikely(file_class_array == nullptr)) {
948+
file_class_max = 0;
942949
return 1;
943950
}
944951
} else {
@@ -980,6 +987,7 @@ int init_stage_class(uint stage_class_sizing) {
980987
&builtin_memory_stage_class, stage_class_max, sizeof(PFS_stage_class),
981988
PFS_stage_class, MYF(MY_ZEROFILL));
982989
if (unlikely(stage_class_array == nullptr)) {
990+
stage_class_max = 0;
983991
return 1;
984992
}
985993
} else {
@@ -1021,6 +1029,7 @@ int init_statement_class(uint statement_class_sizing) {
10211029
&builtin_memory_statement_class, statement_class_max,
10221030
sizeof(PFS_statement_class), PFS_statement_class, MYF(MY_ZEROFILL));
10231031
if (unlikely(statement_class_array == nullptr)) {
1032+
statement_class_max = 0;
10241033
return 1;
10251034
}
10261035
} else {
@@ -1062,6 +1071,7 @@ int init_socket_class(uint socket_class_sizing) {
10621071
&builtin_memory_socket_class, socket_class_max,
10631072
sizeof(PFS_socket_class), PFS_socket_class, MYF(MY_ZEROFILL));
10641073
if (unlikely(socket_class_array == nullptr)) {
1074+
socket_class_max = 0;
10651075
return 1;
10661076
}
10671077
} else {
@@ -1103,6 +1113,7 @@ int init_memory_class(uint memory_class_sizing) {
11031113
&builtin_memory_memory_class, memory_class_max,
11041114
sizeof(PFS_memory_class), PFS_memory_class, MYF(MY_ZEROFILL));
11051115
if (unlikely(memory_class_array.load() == nullptr)) {
1116+
memory_class_max = 0;
11061117
return 1;
11071118
}
11081119
} else {

0 commit comments

Comments
 (0)