Commit d7d5db64 authored by evgen@moonbone.local's avatar evgen@moonbone.local
Browse files

Bug#25172: Not checked buffer size leads to a server crash.

After fix for bug#21798 JOIN stores the pointer to the buffer for sorting
fields. It is used while sorting for grouping and for ordering. If ORDER BY
clause has more elements then the GROUP BY clause then a memory overrun occurs.

Now the length of the ORDER BY list is always passed to the 
make_unireg_sortorder() function and it allocates buffer big enough to be
used for bigger list.
parent f3b3f1ef
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -3611,3 +3611,11 @@ id select_type table type possible_keys key key_len ref rows Extra
1	SIMPLE	t2	range	si,ai	si	5	NULL	2	Using where
1	SIMPLE	t3	eq_ref	PRIMARY,ci	PRIMARY	4	test.t2.a	1	Using where
DROP TABLE t1,t2,t3;
CREATE TABLE t1 ( f1 int primary key, f2 int, f3 int, f4 int, f5 int, f6 int, checked_out int);
CREATE TABLE t2 ( f11 int PRIMARY KEY );
INSERT INTO t1 VALUES (1,1,1,0,0,0,0),(2,1,1,3,8,1,0),(3,1,1,4,12,1,0);
INSERT INTO t2 VALUES (62);
SELECT * FROM t1 LEFT JOIN t2 ON f11 = t1.checked_out GROUP BY f1 ORDER BY f2, f3, f4, f5 LIMIT 0, 1;
f1	f2	f3	f4	f5	f6	checked_out	f11
1	1	1	0	0	0	0	NULL
DROP TABLE t1, t2;
+11 −0
Original line number Diff line number Diff line
@@ -3092,3 +3092,14 @@ SELECT t3.a FROM t1,t2,t3
        t3.c IN ('bb','ee');

DROP TABLE t1,t2,t3;
 
#
# Bug#25172: Not checked buffer size leads to a server crash
#
CREATE TABLE t1 ( f1 int primary key, f2 int, f3 int, f4 int, f5 int, f6 int, checked_out int);
CREATE TABLE t2 ( f11 int PRIMARY KEY );
INSERT INTO t1 VALUES (1,1,1,0,0,0,0),(2,1,1,3,8,1,0),(3,1,1,4,12,1,0);
INSERT INTO t2 VALUES (62);
SELECT * FROM t1 LEFT JOIN t2 ON f11 = t1.checked_out GROUP BY f1 ORDER BY f2, f3, f4, f5 LIMIT 0, 1;
DROP TABLE t1, t2;
+1 −1
Original line number Diff line number Diff line
@@ -142,7 +142,7 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,

  if (order && order->elements)
  {
    uint         length;
    uint         length= 0;
    SORT_FIELD  *sortorder;
    TABLE_LIST   tables;
    List<Item>   fields;
+8 −4
Original line number Diff line number Diff line
@@ -12262,7 +12262,7 @@ static int
create_sort_index(THD *thd, JOIN *join, ORDER *order,
		  ha_rows filesort_limit, ha_rows select_limit)
{
  uint length;
  uint length= 0;
  ha_rows examined_rows;
  TABLE *table;
  SQL_SELECT *select;
@@ -12283,6 +12283,8 @@ create_sort_index(THD *thd, JOIN *join, ORDER *order,
       !(join->select_options & SELECT_BIG_RESULT)) &&
      test_if_skip_sort_order(tab,order,select_limit,0))
    DBUG_RETURN(0);
  for (ORDER *ord= join->order; ord; ord= ord->next)
    length++;
  if (!(join->sortorder= 
        make_unireg_sortorder(order, &length, join->sortorder)))
    goto err;				/* purecov: inspected */
@@ -12690,8 +12692,10 @@ SORT_FIELD *make_unireg_sortorder(ORDER *order, uint *length,
  for (ORDER *tmp = order; tmp; tmp=tmp->next)
    count++;
  if (!sortorder)
    sortorder= (SORT_FIELD*) sql_alloc(sizeof(SORT_FIELD)*(count+1));
    sortorder= (SORT_FIELD*) sql_alloc(sizeof(SORT_FIELD) *
                                       (max(count, *length) + 1));
  pos= sort= sortorder;

  if (!pos)
    return 0;

+1 −1
Original line number Diff line number Diff line
@@ -3883,7 +3883,7 @@ copy_data_between_tables(TABLE *from,TABLE *to,
  Copy_field *copy,*copy_end;
  ulong found_count,delete_count;
  THD *thd= current_thd;
  uint length;
  uint length= 0;
  SORT_FIELD *sortorder;
  READ_RECORD info;
  TABLE_LIST   tables;
Loading