mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 05:21:33 +03:00
Fixed bug 16201: a memory corruption causing crashes due to a too small
buffer for a MY_BITMAP temporary buffer allocated on stack in the function get_best_covering_ror_intersect(). Now the buffer of a proper size is allocated by a request from this function in mem_root. We succeeded to demonstrate the bug only on Windows with a very large database. That's why no test case is provided for in the patch.
This commit is contained in:
@ -442,6 +442,7 @@ typedef struct st_qsel_param {
|
|||||||
|
|
||||||
uint fields_bitmap_size;
|
uint fields_bitmap_size;
|
||||||
MY_BITMAP needed_fields; /* bitmask of fields needed by the query */
|
MY_BITMAP needed_fields; /* bitmask of fields needed by the query */
|
||||||
|
MY_BITMAP tmp_covered_fields;
|
||||||
|
|
||||||
key_map *needed_reg; /* ptr to SQL_SELECT::needed_reg */
|
key_map *needed_reg; /* ptr to SQL_SELECT::needed_reg */
|
||||||
|
|
||||||
@ -1765,6 +1766,7 @@ static int fill_used_fields_bitmap(PARAM *param)
|
|||||||
param->fields_bitmap_size= (table->s->fields/8 + 1);
|
param->fields_bitmap_size= (table->s->fields/8 + 1);
|
||||||
uchar *tmp;
|
uchar *tmp;
|
||||||
uint pk;
|
uint pk;
|
||||||
|
param->tmp_covered_fields.bitmap= 0;
|
||||||
if (!(tmp= (uchar*)alloc_root(param->mem_root,param->fields_bitmap_size)) ||
|
if (!(tmp= (uchar*)alloc_root(param->mem_root,param->fields_bitmap_size)) ||
|
||||||
bitmap_init(¶m->needed_fields, tmp, param->fields_bitmap_size*8,
|
bitmap_init(¶m->needed_fields, tmp, param->fields_bitmap_size*8,
|
||||||
FALSE))
|
FALSE))
|
||||||
@ -3202,11 +3204,14 @@ TRP_ROR_INTERSECT *get_best_covering_ror_intersect(PARAM *param,
|
|||||||
/*I=set of all covering indexes */
|
/*I=set of all covering indexes */
|
||||||
ror_scan_mark= tree->ror_scans;
|
ror_scan_mark= tree->ror_scans;
|
||||||
|
|
||||||
uchar buf[MAX_KEY/8+1];
|
MY_BITMAP *covered_fields= ¶m->tmp_covered_fields;
|
||||||
MY_BITMAP covered_fields;
|
if (!covered_fields->bitmap)
|
||||||
if (bitmap_init(&covered_fields, buf, nbits, FALSE))
|
covered_fields->bitmap= (uchar*)alloc_root(param->mem_root,
|
||||||
|
param->fields_bitmap_size);
|
||||||
|
if (!covered_fields->bitmap ||
|
||||||
|
bitmap_init(covered_fields, covered_fields->bitmap, nbits, FALSE))
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
bitmap_clear_all(&covered_fields);
|
bitmap_clear_all(covered_fields);
|
||||||
|
|
||||||
double total_cost= 0.0f;
|
double total_cost= 0.0f;
|
||||||
ha_rows records=0;
|
ha_rows records=0;
|
||||||
@ -3225,7 +3230,7 @@ TRP_ROR_INTERSECT *get_best_covering_ror_intersect(PARAM *param,
|
|||||||
*/
|
*/
|
||||||
for (ROR_SCAN_INFO **scan= ror_scan_mark; scan != ror_scans_end; ++scan)
|
for (ROR_SCAN_INFO **scan= ror_scan_mark; scan != ror_scans_end; ++scan)
|
||||||
{
|
{
|
||||||
bitmap_subtract(&(*scan)->covered_fields, &covered_fields);
|
bitmap_subtract(&(*scan)->covered_fields, covered_fields);
|
||||||
(*scan)->used_fields_covered=
|
(*scan)->used_fields_covered=
|
||||||
bitmap_bits_set(&(*scan)->covered_fields);
|
bitmap_bits_set(&(*scan)->covered_fields);
|
||||||
(*scan)->first_uncovered_field=
|
(*scan)->first_uncovered_field=
|
||||||
@ -3247,8 +3252,8 @@ TRP_ROR_INTERSECT *get_best_covering_ror_intersect(PARAM *param,
|
|||||||
if (total_cost > read_time)
|
if (total_cost > read_time)
|
||||||
DBUG_RETURN(NULL);
|
DBUG_RETURN(NULL);
|
||||||
/* F=F-covered by first(I) */
|
/* F=F-covered by first(I) */
|
||||||
bitmap_union(&covered_fields, &(*ror_scan_mark)->covered_fields);
|
bitmap_union(covered_fields, &(*ror_scan_mark)->covered_fields);
|
||||||
all_covered= bitmap_is_subset(¶m->needed_fields, &covered_fields);
|
all_covered= bitmap_is_subset(¶m->needed_fields, covered_fields);
|
||||||
} while ((++ror_scan_mark < ror_scans_end) && !all_covered);
|
} while ((++ror_scan_mark < ror_scans_end) && !all_covered);
|
||||||
|
|
||||||
if (!all_covered || (ror_scan_mark - tree->ror_scans) == 1)
|
if (!all_covered || (ror_scan_mark - tree->ror_scans) == 1)
|
||||||
|
Reference in New Issue
Block a user