mirror of
https://github.com/MariaDB/server.git
synced 2025-12-01 17:39:21 +03:00
MDEV-20311 row_ins_step accesses unitialized memory
ins_node_create() does not initialize all members of que_common_t, so zero-init them with mem_heap_zalloc(). Handle out-of-memory correctly. Init insert_node->common.parent to fulfill the contract of thr usage. Free insert_node subtree at row_update_vers_insert() exit.
This commit is contained in:
@@ -74,7 +74,11 @@ ins_node_create(
|
|||||||
ins_node_t* node;
|
ins_node_t* node;
|
||||||
|
|
||||||
node = static_cast<ins_node_t*>(
|
node = static_cast<ins_node_t*>(
|
||||||
mem_heap_alloc(heap, sizeof(ins_node_t)));
|
mem_heap_zalloc(heap, sizeof(ins_node_t)));
|
||||||
|
|
||||||
|
if (!node) {
|
||||||
|
return(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
node->common.type = QUE_NODE_INSERT;
|
node->common.type = QUE_NODE_INSERT;
|
||||||
|
|
||||||
@@ -82,12 +86,6 @@ ins_node_create(
|
|||||||
|
|
||||||
node->state = INS_NODE_SET_IX_LOCK;
|
node->state = INS_NODE_SET_IX_LOCK;
|
||||||
node->table = table;
|
node->table = table;
|
||||||
node->index = NULL;
|
|
||||||
node->entry = NULL;
|
|
||||||
|
|
||||||
node->select = NULL;
|
|
||||||
|
|
||||||
node->trx_id = 0;
|
|
||||||
|
|
||||||
node->entry_sys_heap = mem_heap_create(128);
|
node->entry_sys_heap = mem_heap_create(128);
|
||||||
|
|
||||||
|
|||||||
@@ -2150,7 +2150,9 @@ This is used in UPDATE CASCADE/SET NULL of a system versioning table.
|
|||||||
@return DB_SUCCESS or some error */
|
@return DB_SUCCESS or some error */
|
||||||
static dberr_t row_update_vers_insert(que_thr_t* thr, upd_node_t* node)
|
static dberr_t row_update_vers_insert(que_thr_t* thr, upd_node_t* node)
|
||||||
{
|
{
|
||||||
const trx_t* trx = thr_get_trx(thr);
|
trx_t* trx = thr_get_trx(thr);
|
||||||
|
dfield_t* row_end;
|
||||||
|
char row_end_data[8];
|
||||||
dict_table_t* table = node->table;
|
dict_table_t* table = node->table;
|
||||||
ut_ad(table->versioned());
|
ut_ad(table->versioned());
|
||||||
|
|
||||||
@@ -2161,10 +2163,15 @@ static dberr_t row_update_vers_insert(que_thr_t* thr, upd_node_t* node)
|
|||||||
ins_node_t* insert_node =
|
ins_node_t* insert_node =
|
||||||
ins_node_create(INS_DIRECT, table, node->historical_heap);
|
ins_node_create(INS_DIRECT, table, node->historical_heap);
|
||||||
|
|
||||||
|
if (!insert_node) {
|
||||||
|
trx->error_state = DB_OUT_OF_MEMORY;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
insert_node->common.parent = thr;
|
||||||
ins_node_set_new_row(insert_node, row);
|
ins_node_set_new_row(insert_node, row);
|
||||||
|
|
||||||
dfield_t* row_end = dtuple_get_nth_field(row, table->vers_end);
|
row_end = dtuple_get_nth_field(row, table->vers_end);
|
||||||
char row_end_data[8];
|
|
||||||
if (dict_table_get_nth_col(table, table->vers_end)->vers_native()) {
|
if (dict_table_get_nth_col(table, table->vers_end)->vers_native()) {
|
||||||
mach_write_to_8(row_end_data, trx->id);
|
mach_write_to_8(row_end_data, trx->id);
|
||||||
dfield_set_data(row_end, row_end_data, 8);
|
dfield_set_data(row_end, row_end_data, 8);
|
||||||
@@ -2202,6 +2209,7 @@ static dberr_t row_update_vers_insert(que_thr_t* thr, upd_node_t* node)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
exit:
|
exit:
|
||||||
|
que_graph_free_recursive(insert_node);
|
||||||
mem_heap_free(node->historical_heap);
|
mem_heap_free(node->historical_heap);
|
||||||
node->historical_heap = NULL;
|
node->historical_heap = NULL;
|
||||||
return trx->error_state;
|
return trx->error_state;
|
||||||
|
|||||||
Reference in New Issue
Block a user