MDEV-24964 : Heap-buffer-overflow on wsrep_schema.cc ::remove_fragments
Problem was that we used heap allocated key using too small array. Fixed by using dynamic memory allocation using actual needed size.
This commit is contained in:
parent
f2428b9c24
commit
d1eeb4b839
@ -566,14 +566,24 @@ static int end_index_scan(TABLE* table) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void make_key(TABLE* table, uchar* key, key_part_map* map, int parts) {
|
static void make_key(TABLE* table, uchar** key, key_part_map* map, int parts) {
|
||||||
uint prefix_length= 0;
|
uint prefix_length= 0;
|
||||||
KEY_PART_INFO* key_part= table->key_info->key_part;
|
KEY_PART_INFO* key_part= table->key_info->key_part;
|
||||||
|
|
||||||
for (int i=0; i < parts; i++)
|
for (int i=0; i < parts; i++)
|
||||||
prefix_length += key_part[i].store_length;
|
prefix_length += key_part[i].store_length;
|
||||||
|
|
||||||
*map= make_prev_keypart_map(parts);
|
*map= make_prev_keypart_map(parts);
|
||||||
key_copy(key, table->record[0], table->key_info, prefix_length);
|
|
||||||
|
if (!(*key= (uchar *) my_malloc(prefix_length + 1, MYF(MY_WME))))
|
||||||
|
{
|
||||||
|
WSREP_ERROR("Failed to allocate memory for key prefix_length %u", prefix_length);
|
||||||
|
assert(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
key_copy(*key, table->record[0], table->key_info, prefix_length);
|
||||||
}
|
}
|
||||||
|
|
||||||
} /* namespace Wsrep_schema_impl */
|
} /* namespace Wsrep_schema_impl */
|
||||||
|
|
||||||
|
|
||||||
@ -958,7 +968,7 @@ int Wsrep_schema::update_fragment_meta(THD* thd,
|
|||||||
|
|
||||||
Wsrep_schema_impl::binlog_off binlog_off(thd);
|
Wsrep_schema_impl::binlog_off binlog_off(thd);
|
||||||
int error;
|
int error;
|
||||||
uchar key[MAX_KEY_LENGTH+MAX_FIELD_WIDTH];
|
uchar *key=NULL;
|
||||||
key_part_map key_map= 0;
|
key_part_map key_map= 0;
|
||||||
TABLE* frag_table= 0;
|
TABLE* frag_table= 0;
|
||||||
|
|
||||||
@ -973,7 +983,7 @@ int Wsrep_schema::update_fragment_meta(THD* thd,
|
|||||||
Wsrep_schema_impl::store(frag_table, 0, ws_meta.server_id());
|
Wsrep_schema_impl::store(frag_table, 0, ws_meta.server_id());
|
||||||
Wsrep_schema_impl::store(frag_table, 1, ws_meta.transaction_id().get());
|
Wsrep_schema_impl::store(frag_table, 1, ws_meta.transaction_id().get());
|
||||||
Wsrep_schema_impl::store(frag_table, 2, -1);
|
Wsrep_schema_impl::store(frag_table, 2, -1);
|
||||||
Wsrep_schema_impl::make_key(frag_table, key, &key_map, 3);
|
Wsrep_schema_impl::make_key(frag_table, &key, &key_map, 3);
|
||||||
|
|
||||||
if ((error= Wsrep_schema_impl::init_for_index_scan(frag_table,
|
if ((error= Wsrep_schema_impl::init_for_index_scan(frag_table,
|
||||||
key, key_map)))
|
key, key_map)))
|
||||||
@ -987,9 +997,11 @@ int Wsrep_schema::update_fragment_meta(THD* thd,
|
|||||||
}
|
}
|
||||||
Wsrep_schema_impl::finish_stmt(thd);
|
Wsrep_schema_impl::finish_stmt(thd);
|
||||||
thd->lex->restore_backup_query_tables_list(&query_tables_list_backup);
|
thd->lex->restore_backup_query_tables_list(&query_tables_list_backup);
|
||||||
|
my_free(key);
|
||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
my_free(key);
|
||||||
/* Copy the original record to frag_table->record[1] */
|
/* Copy the original record to frag_table->record[1] */
|
||||||
store_record(frag_table, record[1]);
|
store_record(frag_table, record[1]);
|
||||||
|
|
||||||
@ -1024,7 +1036,7 @@ static int remove_fragment(THD* thd,
|
|||||||
seqno.get());
|
seqno.get());
|
||||||
int ret= 0;
|
int ret= 0;
|
||||||
int error;
|
int error;
|
||||||
uchar key[MAX_KEY_LENGTH+MAX_FIELD_WIDTH];
|
uchar *key= NULL;
|
||||||
key_part_map key_map= 0;
|
key_part_map key_map= 0;
|
||||||
|
|
||||||
DBUG_ASSERT(server_id.is_undefined() == false);
|
DBUG_ASSERT(server_id.is_undefined() == false);
|
||||||
@ -1038,7 +1050,7 @@ static int remove_fragment(THD* thd,
|
|||||||
Wsrep_schema_impl::store(frag_table, 0, server_id);
|
Wsrep_schema_impl::store(frag_table, 0, server_id);
|
||||||
Wsrep_schema_impl::store(frag_table, 1, transaction_id.get());
|
Wsrep_schema_impl::store(frag_table, 1, transaction_id.get());
|
||||||
Wsrep_schema_impl::store(frag_table, 2, seqno.get());
|
Wsrep_schema_impl::store(frag_table, 2, seqno.get());
|
||||||
Wsrep_schema_impl::make_key(frag_table, key, &key_map, 3);
|
Wsrep_schema_impl::make_key(frag_table, &key, &key_map, 3);
|
||||||
|
|
||||||
if ((error= Wsrep_schema_impl::init_for_index_scan(frag_table,
|
if ((error= Wsrep_schema_impl::init_for_index_scan(frag_table,
|
||||||
key,
|
key,
|
||||||
@ -1060,6 +1072,8 @@ static int remove_fragment(THD* thd,
|
|||||||
ret= 1;
|
ret= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (key)
|
||||||
|
my_free(key);
|
||||||
Wsrep_schema_impl::end_index_scan(frag_table);
|
Wsrep_schema_impl::end_index_scan(frag_table);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -1147,7 +1161,7 @@ int Wsrep_schema::replay_transaction(THD* orig_thd,
|
|||||||
int ret= 1;
|
int ret= 1;
|
||||||
int error;
|
int error;
|
||||||
TABLE* frag_table= 0;
|
TABLE* frag_table= 0;
|
||||||
uchar key[MAX_KEY_LENGTH+MAX_FIELD_WIDTH];
|
uchar *key=NULL;
|
||||||
key_part_map key_map= 0;
|
key_part_map key_map= 0;
|
||||||
|
|
||||||
for (std::vector<wsrep::seqno>::const_iterator i= fragments.begin();
|
for (std::vector<wsrep::seqno>::const_iterator i= fragments.begin();
|
||||||
@ -1164,7 +1178,7 @@ int Wsrep_schema::replay_transaction(THD* orig_thd,
|
|||||||
Wsrep_schema_impl::store(frag_table, 0, ws_meta.server_id());
|
Wsrep_schema_impl::store(frag_table, 0, ws_meta.server_id());
|
||||||
Wsrep_schema_impl::store(frag_table, 1, ws_meta.transaction_id().get());
|
Wsrep_schema_impl::store(frag_table, 1, ws_meta.transaction_id().get());
|
||||||
Wsrep_schema_impl::store(frag_table, 2, i->get());
|
Wsrep_schema_impl::store(frag_table, 2, i->get());
|
||||||
Wsrep_schema_impl::make_key(frag_table, key, &key_map, 3);
|
Wsrep_schema_impl::make_key(frag_table, &key, &key_map, 3);
|
||||||
|
|
||||||
int error= Wsrep_schema_impl::init_for_index_scan(frag_table,
|
int error= Wsrep_schema_impl::init_for_index_scan(frag_table,
|
||||||
key,
|
key,
|
||||||
@ -1211,6 +1225,7 @@ int Wsrep_schema::replay_transaction(THD* orig_thd,
|
|||||||
Wsrep_schema_impl::finish_stmt(&thd);
|
Wsrep_schema_impl::finish_stmt(&thd);
|
||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
error= Wsrep_schema_impl::init_for_index_scan(frag_table,
|
error= Wsrep_schema_impl::init_for_index_scan(frag_table,
|
||||||
key,
|
key,
|
||||||
key_map);
|
key_map);
|
||||||
@ -1224,6 +1239,7 @@ int Wsrep_schema::replay_transaction(THD* orig_thd,
|
|||||||
}
|
}
|
||||||
|
|
||||||
error= Wsrep_schema_impl::delete_row(frag_table);
|
error= Wsrep_schema_impl::delete_row(frag_table);
|
||||||
|
|
||||||
if (error)
|
if (error)
|
||||||
{
|
{
|
||||||
WSREP_WARN("Could not delete row from streaming log table: %d", error);
|
WSREP_WARN("Could not delete row from streaming log table: %d", error);
|
||||||
@ -1233,8 +1249,12 @@ int Wsrep_schema::replay_transaction(THD* orig_thd,
|
|||||||
}
|
}
|
||||||
Wsrep_schema_impl::end_index_scan(frag_table);
|
Wsrep_schema_impl::end_index_scan(frag_table);
|
||||||
Wsrep_schema_impl::finish_stmt(&thd);
|
Wsrep_schema_impl::finish_stmt(&thd);
|
||||||
|
my_free(key);
|
||||||
|
key= NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (key)
|
||||||
|
my_free(key);
|
||||||
DBUG_RETURN(ret);
|
DBUG_RETURN(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user