Skip to content

Commit 10e01b5

Browse files
committed
Fix USE_AFTER_FREE (CWE-416)
A static analysis tool suggested that in the function row_merge_read_clustered_index(), ut_free(nonnull) could be invoked twice for nonnull!=NULL. While a manual review of the code disproved this, it should not hurt to clean up the code so that the static analysis tool will not complain. index_tuple_info_t::insert(), row_mtuple_cmp(): Remove the parameter mtr_committed, which duplicated !mtr->is_active(). row_merge_read_clustered_index(): Initialize row_heap = NULL. Remove a duplicated call mem_heap_empty(row_heap) that was inadvertently added in commit cb1e76e. Replace a "goto func_exit" with "break", to get consistent error handling for both failures to create or write a temporary file. end_of_index: Assign row_heap=NULL and nonnull=NULL to prevent double freeing. func_exit: Check for row_heap!=NULL before invoking mem_heap_free(). Closes #959
1 parent 32eeed2 commit 10e01b5

File tree

1 file changed

+25
-39
lines changed

1 file changed

+25
-39
lines changed

storage/innobase/row/row0merge.cc

Lines changed: 25 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -115,14 +115,12 @@ class index_tuple_info_t {
115115
@param[in,out] row_heap memory heap
116116
@param[in] pcur cluster index scanning cursor
117117
@param[in,out] scan_mtr mini-transaction for pcur
118-
@param[out] mtr_committed whether scan_mtr got committed
119118
@return DB_SUCCESS if successful, else error number */
120-
dberr_t insert(
119+
inline dberr_t insert(
121120
trx_id_t trx_id,
122121
mem_heap_t* row_heap,
123122
btr_pcur_t* pcur,
124-
mtr_t* scan_mtr,
125-
bool* mtr_committed)
123+
mtr_t* scan_mtr)
126124
{
127125
big_rec_t* big_rec;
128126
rec_t* rec;
@@ -150,11 +148,10 @@ class index_tuple_info_t {
150148
ut_ad(dtuple);
151149

152150
if (log_sys->check_flush_or_checkpoint) {
153-
if (!(*mtr_committed)) {
151+
if (scan_mtr->is_active()) {
154152
btr_pcur_move_to_prev_on_page(pcur);
155153
btr_pcur_store_position(pcur, scan_mtr);
156-
mtr_commit(scan_mtr);
157-
*mtr_committed = true;
154+
scan_mtr->commit();
158155
}
159156

160157
log_free_check();
@@ -1589,7 +1586,6 @@ row_mtuple_cmp(
15891586
@param[in,out] sp_heap heap for tuples
15901587
@param[in,out] pcur cluster index cursor
15911588
@param[in,out] mtr mini transaction
1592-
@param[in,out] mtr_committed whether scan_mtr got committed
15931589
@return DB_SUCCESS or error number */
15941590
static
15951591
dberr_t
@@ -1600,8 +1596,7 @@ row_merge_spatial_rows(
16001596
mem_heap_t* row_heap,
16011597
mem_heap_t* sp_heap,
16021598
btr_pcur_t* pcur,
1603-
mtr_t* mtr,
1604-
bool* mtr_committed)
1599+
mtr_t* mtr)
16051600
{
16061601
dberr_t err = DB_SUCCESS;
16071602

@@ -1612,9 +1607,7 @@ row_merge_spatial_rows(
16121607
ut_ad(sp_heap != NULL);
16131608

16141609
for (ulint j = 0; j < num_spatial; j++) {
1615-
err = sp_tuples[j]->insert(
1616-
trx_id, row_heap,
1617-
pcur, mtr, mtr_committed);
1610+
err = sp_tuples[j]->insert(trx_id, row_heap, pcur, mtr);
16181611

16191612
if (err != DB_SUCCESS) {
16201613
return(err);
@@ -1716,7 +1709,7 @@ row_merge_read_clustered_index(
17161709
struct TABLE* eval_table)
17171710
{
17181711
dict_index_t* clust_index; /* Clustered index */
1719-
mem_heap_t* row_heap; /* Heap memory to create
1712+
mem_heap_t* row_heap = NULL;/* Heap memory to create
17201713
clustered index tuples */
17211714
row_merge_buf_t** merge_buf; /* Temporary list for records*/
17221715
mem_heap_t* v_heap = NULL; /* Heap memory to process large
@@ -1903,22 +1896,19 @@ row_merge_read_clustered_index(
19031896

19041897
/* Scan the clustered index. */
19051898
for (;;) {
1906-
const rec_t* rec;
1907-
ulint* offsets;
1908-
const dtuple_t* row;
1909-
row_ext_t* ext;
1910-
page_cur_t* cur = btr_pcur_get_page_cur(&pcur);
1911-
1912-
mem_heap_empty(row_heap);
1913-
19141899
/* Do not continue if table pages are still encrypted */
1915-
if (!old_table->is_readable() ||
1916-
!new_table->is_readable()) {
1900+
if (!old_table->is_readable() || !new_table->is_readable()) {
19171901
err = DB_DECRYPTION_FAILED;
19181902
trx->error_key_num = 0;
19191903
goto func_exit;
19201904
}
19211905

1906+
const rec_t* rec;
1907+
ulint* offsets;
1908+
const dtuple_t* row;
1909+
row_ext_t* ext;
1910+
page_cur_t* cur = btr_pcur_get_page_cur(&pcur);
1911+
19221912
mem_heap_empty(row_heap);
19231913

19241914
page_cur_move_to_next(cur);
@@ -1953,18 +1943,15 @@ row_merge_read_clustered_index(
19531943
dbug_run_purge = true;);
19541944

19551945
/* Insert the cached spatial index rows. */
1956-
bool mtr_committed = false;
1957-
19581946
err = row_merge_spatial_rows(
19591947
trx->id, sp_tuples, num_spatial,
1960-
row_heap, sp_heap, &pcur,
1961-
&mtr, &mtr_committed);
1948+
row_heap, sp_heap, &pcur, &mtr);
19621949

19631950
if (err != DB_SUCCESS) {
19641951
goto func_exit;
19651952
}
19661953

1967-
if (mtr_committed) {
1954+
if (!mtr.is_active()) {
19681955
goto scan_next;
19691956
}
19701957

@@ -2019,7 +2006,9 @@ row_merge_read_clustered_index(
20192006
row = NULL;
20202007
mtr_commit(&mtr);
20212008
mem_heap_free(row_heap);
2009+
row_heap = NULL;
20222010
ut_free(nonnull);
2011+
nonnull = NULL;
20232012
goto write_buffers;
20242013
}
20252014
} else {
@@ -2347,8 +2336,6 @@ row_merge_read_clustered_index(
23472336
/* Temporary File is not used.
23482337
so insert sorted block to the index */
23492338
if (row != NULL) {
2350-
bool mtr_committed = false;
2351-
23522339
/* We have to do insert the
23532340
cached spatial index rows, since
23542341
after the mtr_commit, the cluster
@@ -2359,8 +2346,7 @@ row_merge_read_clustered_index(
23592346
trx->id, sp_tuples,
23602347
num_spatial,
23612348
row_heap, sp_heap,
2362-
&pcur, &mtr,
2363-
&mtr_committed);
2349+
&pcur, &mtr);
23642350

23652351
if (err != DB_SUCCESS) {
23662352
goto func_exit;
@@ -2375,13 +2361,13 @@ row_merge_read_clustered_index(
23752361
current row will be invalid, and
23762362
we must reread it on the next
23772363
loop iteration. */
2378-
if (!mtr_committed) {
2364+
if (mtr.is_active()) {
23792365
btr_pcur_move_to_prev_on_page(
23802366
&pcur);
23812367
btr_pcur_store_position(
23822368
&pcur, &mtr);
23832369

2384-
mtr_commit(&mtr);
2370+
mtr.commit();
23852371
}
23862372
}
23872373

@@ -2536,7 +2522,7 @@ row_merge_read_clustered_index(
25362522
buf->n_tuples, path) < 0) {
25372523
err = DB_OUT_OF_MEMORY;
25382524
trx->error_key_num = i;
2539-
goto func_exit;
2525+
break;
25402526
}
25412527

25422528
/* Ensure that duplicates in the
@@ -2614,12 +2600,12 @@ row_merge_read_clustered_index(
26142600
}
26152601

26162602
func_exit:
2617-
/* row_merge_spatial_rows may have committed
2618-
the mtr before an error occurs. */
26192603
if (mtr.is_active()) {
26202604
mtr_commit(&mtr);
26212605
}
2622-
mem_heap_free(row_heap);
2606+
if (row_heap) {
2607+
mem_heap_free(row_heap);
2608+
}
26232609
ut_free(nonnull);
26242610

26252611
all_done:

0 commit comments

Comments
 (0)