• Alexey Kopytov's avatar
    Bug #54476: crash when group_concat and 'with rollup' in · 1837dcfe
    Alexey Kopytov authored
                         prepared statements
    
    Using GROUP_CONCAT() together with the WITH ROLLUP modifier
    could crash the server.
    
    The reason was a combination of several facts:
    
    1. The Item_func_group_concat class stores pointers to ORDER
    objects representing the columns in the ORDER BY clause of
    GROUP_CONCAT().
    
    2. find_order_in_list() called from
    Item_func_group_concat::setup() modifies the ORDER objects so
    that their 'item' member points to the arguments list
    allocated in the Item_func_group_concat constructor.
    
    3. In some cases (e.g. in JOIN::rollup_make_fields) a copy of
    the original Item_func_group_concat object could be created by
    using the Item_func_group_concat::Item_func_group_concat(THD
    *thd, Item_func_group_concat *item) copy constructor. The
    latter essentially creates a shallow copy of the source
    object. Memory for the arguments array is allocated on
    thd->mem_root, but the pointers for arguments and ORDER are
    copied verbatim.
    
    What happens in the test case is that when executing the query
    for the first time, after a copy of the original
    Item_func_group_concat object has been created by
    JOIN::rollup_make_fields(), find_order_in_list() is called for
    this new object. It then resolves ORDER BY by modifying the
    ORDER objects so that they point to elements of the arguments
    array which is local to the cloned object. When thd->mem_root
    is freed upon completing the execution, pointers in the ORDER
    objects become invalid. Those ORDER objects, however, are also
    shared with the original Item_func_group_concat object which is
    preserved between executions of a prepared statement. So the
    first call to find_order_in_list() for the original object on
    the second execution tries to dereference an invalid pointer.
    
    The solution is to create copies of the ORDER objects when
    copying Item_func_group_concat to not leave any stale pointers
    in other instances with different lifecycles.
    
    
    
    mysql-test/r/func_gconcat.result:
      Test case for bug #54476.
    mysql-test/t/func_gconcat.test:
      Test case for bug #54476.
    sql/item_sum.cc:
      Copy the ORDER objects pointed to by the elements of the 
      'order' array in the copy constructor of 
      Item_func_group_concat.
    sql/table.h:
      Removed the unused 'item_copy' member of the ORDER class.
    1837dcfe
func_gconcat.test 23.8 KB