Commit 4cb69791 authored by Michael Widenius's avatar Michael Widenius

Added detection of memory overwrite with multi_malloc

This detected two bugs in the code, which are both fixed
parent c00c12df
......@@ -17,6 +17,11 @@
#include "mysys_priv.h"
#include <stdarg.h>
#ifndef DBUG_OFF
/* Put a protected barrier after every element when using my_multi_malloc() */
#define ALLOC_BARRIER
#endif
/*
Malloc many pointers at the same time
Only ptr1 can be free'd, and doing this will free all
......@@ -45,6 +50,9 @@ void* my_multi_malloc(PSI_memory_key key, myf myFlags, ...)
{
length=va_arg(args,uint);
tot_length+=ALIGN_SIZE(length);
#ifdef ALLOC_BARRIER
tot_length+= ALIGN_SIZE(1);
#endif
}
va_end(args);
......@@ -58,6 +66,10 @@ void* my_multi_malloc(PSI_memory_key key, myf myFlags, ...)
*ptr=res;
length=va_arg(args,uint);
res+=ALIGN_SIZE(length);
#ifdef ALLOC_BARRIER
TRASH_FREE(res, ALIGN_SIZE(1));
res+= ALIGN_SIZE(1);
#endif
}
va_end(args);
DBUG_RETURN((void*) start);
......@@ -89,6 +101,9 @@ void *my_multi_malloc_large(PSI_memory_key key, myf myFlags, ...)
{
length=va_arg(args,ulonglong);
tot_length+=ALIGN_SIZE(length);
#ifdef ALLOC_BARRIER
tot_length+= ALIGN_SIZE(1);
#endif
}
va_end(args);
......@@ -102,6 +117,10 @@ void *my_multi_malloc_large(PSI_memory_key key, myf myFlags, ...)
*ptr=res;
length=va_arg(args,ulonglong);
res+=ALIGN_SIZE(length);
#ifdef ALLOC_BARRIER
TRASH_FREE(res, ALIGN_SIZE(1));
res+= ALIGN_SIZE(1);
#endif
}
va_end(args);
DBUG_RETURN((void*) start);
......
......@@ -25,6 +25,11 @@
#include <sys/mman.h>
#endif
#ifndef DBUG_OFF
/* Put a protected barrier after every element when using multi_alloc_root() */
#define ALLOC_BARRIER
#endif
#undef EXTRA_DEBUG
#define EXTRA_DEBUG
......@@ -396,6 +401,9 @@ void *multi_alloc_root(MEM_ROOT *root, ...)
{
length= va_arg(args, uint);
tot_length+= ALIGN_SIZE(length);
#ifdef ALLOC_BARRIER
tot_length+= ALIGN_SIZE(1);
#endif
}
va_end(args);
......@@ -409,6 +417,10 @@ void *multi_alloc_root(MEM_ROOT *root, ...)
*ptr= res;
length= va_arg(args, uint);
res+= ALIGN_SIZE(length);
#ifdef ALLOC_BARRIER
TRASH_FREE(res, ALIGN_SIZE(1));
res+= ALIGN_SIZE(1);
#endif
}
va_end(args);
DBUG_RETURN((void*) start);
......
......@@ -6276,6 +6276,7 @@ class TMP_TABLE_PARAM :public Sql_alloc
@see opt_sum_query, count_field_types
*/
uint sum_func_count;
uint copy_func_count; // Allocated copy fields
uint hidden_field_count;
uint group_parts,group_length,group_null_parts;
uint quick_group;
......
......@@ -5357,7 +5357,7 @@ make_join_statistics(JOIN *join, List<TABLE_LIST> &tables_list,
/* Initialize POSITION objects */
for (i=0 ; i <= table_count ; i++)
(void) new ((char*) (join->positions + i)) POSITION;
for (i=0 ; i <= sort_space ; i++)
for (i=0 ; i < sort_space ; i++)
(void) new ((char*) (join->sort_positions + i)) POSITION;
join->best_ref= stat_vector;
......@@ -20631,6 +20631,7 @@ TABLE *Create_tmp_table::start(THD *thd,
*/
if (param->precomputed_group_by)
copy_func_count+= param->sum_func_count;
param->copy_func_count= copy_func_count;
init_sql_alloc(key_memory_TABLE, &own_root, TABLE_ALLOC_BLOCK_SIZE, 0,
MYF(MY_THREAD_SPECIFIC));
......@@ -20837,8 +20838,9 @@ bool Create_tmp_table::add_fields(THD *thd,
We here distinguish between UNION and multi-table-updates by the fact
that in the later case group is set to the row pointer.
The test for item->marker == 4 is ensure we don't create a group-by
key over a bit field as heap tables can't handle that.
The test for item->marker == MARKER_NULL_KEY is ensure we
don't create a group-by key over a bit field as heap tables
can't handle that.
*/
DBUG_ASSERT(!param->schema_table);
Field *new_field=
......@@ -20905,6 +20907,7 @@ bool Create_tmp_table::add_fields(THD *thd,
new_field->flags|= FIELD_PART_OF_TMP_UNIQUE;
}
}
DBUG_ASSERT(fieldnr == m_field_count[other] + m_field_count[distinct]);
DBUG_ASSERT(m_blob_count == m_blobs_count[other] + m_blobs_count[distinct]);
share->fields= fieldnr;
......@@ -20912,7 +20915,9 @@ bool Create_tmp_table::add_fields(THD *thd,
table->field[fieldnr]= 0; // End marker
share->blob_field[m_blob_count]= 0; // End marker
copy_func[0]= 0; // End marker
DBUG_ASSERT((copy_func - param->items_to_copy) <= param->copy_func_count);
param->func_count= (uint) (copy_func - param->items_to_copy);
share->column_bitmap_size= bitmap_buffer_size(share->fields);
thd->mem_root= mem_root_save;
......@@ -344,6 +344,7 @@ select_unit::create_result_table(THD *thd_arg, List<Item> *column_types,
DBUG_ASSERT(table == 0);
tmp_table_param.init();
tmp_table_param.field_count= column_types->elements;
tmp_table_param.func_count= tmp_table_param.field_count;
tmp_table_param.bit_fields_as_long= bit_fields_as_long;
tmp_table_param.hidden_field_count= hidden;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment