Permalink
Browse files

Bug#26390632: CREATE TABLE CAN CAUSE MYSQL TO EXIT.

Analysis
========
CREATE TABLE of InnoDB table with a partition name
which exceeds the path limit can cause the server
to exit.

During the preparation of the partition name,
there was no check to identify whether the complete
path name for partition exceeds the max supported
path length, causing the server to exit during
subsequent processing.

Fix
===
During the preparation of partition name, check and report
an error if the partition path name exceeds the maximum path
name limit.

This is a 5.5 patch.
  • Loading branch information...
Nisha Gopalakrishnan
Nisha Gopalakrishnan committed Aug 16, 2017
1 parent ebd96c3 commit be901b60ae59c93848c829d1b0b2cb523ab8692e
Showing with 204 additions and 129 deletions.
  1. +91 −59 sql/ha_partition.cc
  2. +110 −67 sql/sql_partition.cc
  3. +3 −3 sql/sql_partition.h
View
@@ -1,5 +1,5 @@
/*
Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
Copyright (c) 2005, 2017, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -624,7 +624,7 @@ int ha_partition::create(const char *name, TABLE *table_arg,
int ha_partition::drop_partitions(const char *path)
{
List_iterator<partition_element> part_it(m_part_info->partitions);
char part_name_buff[FN_REFLEN];
char part_name_buff[FN_REFLEN + 1];
uint num_parts= m_part_info->partitions.elements;
uint num_subparts= m_part_info->num_subparts;
uint i= 0;
@@ -657,9 +657,12 @@ int ha_partition::drop_partitions(const char *path)
{
partition_element *sub_elem= sub_it++;
part= i * num_subparts + j;
create_subpartition_name(part_name_buff, path,
part_elem->partition_name,
sub_elem->partition_name, name_variant);
if ((ret_error= create_subpartition_name(part_name_buff, path,
part_elem->partition_name,
sub_elem->partition_name,
name_variant)))
error= ret_error;
file= m_file[part];
DBUG_PRINT("info", ("Drop subpartition %s", part_name_buff));
if ((ret_error= file->ha_delete_table(part_name_buff)))
@@ -670,9 +673,11 @@ int ha_partition::drop_partitions(const char *path)
}
else
{
create_partition_name(part_name_buff, path,
part_elem->partition_name, name_variant,
TRUE);
if ((ret_error= create_partition_name(part_name_buff, path,
part_elem->partition_name,
name_variant, TRUE)))
error= ret_error;
file= m_file[i];
DBUG_PRINT("info", ("Drop partition %s", part_name_buff));
if ((ret_error= file->ha_delete_table(part_name_buff)))
@@ -714,8 +719,8 @@ int ha_partition::rename_partitions(const char *path)
{
List_iterator<partition_element> part_it(m_part_info->partitions);
List_iterator<partition_element> temp_it(m_part_info->temp_partitions);
char part_name_buff[FN_REFLEN];
char norm_name_buff[FN_REFLEN];
char part_name_buff[FN_REFLEN + 1];
char norm_name_buff[FN_REFLEN + 1];
uint num_parts= m_part_info->partitions.elements;
uint part_count= 0;
uint num_subparts= m_part_info->num_subparts;
@@ -757,10 +762,11 @@ int ha_partition::rename_partitions(const char *path)
{
sub_elem= sub_it++;
file= m_reorged_file[part_count++];
create_subpartition_name(norm_name_buff, path,
part_elem->partition_name,
sub_elem->partition_name,
NORMAL_PART_NAME);
if ((ret_error= create_subpartition_name(norm_name_buff, path,
part_elem->partition_name,
sub_elem->partition_name,
NORMAL_PART_NAME)))
error= ret_error;
DBUG_PRINT("info", ("Delete subpartition %s", norm_name_buff));
if ((ret_error= file->ha_delete_table(norm_name_buff)))
error= ret_error;
@@ -773,9 +779,11 @@ int ha_partition::rename_partitions(const char *path)
else
{
file= m_reorged_file[part_count++];
create_partition_name(norm_name_buff, path,
part_elem->partition_name, NORMAL_PART_NAME,
TRUE);
if ((ret_error= create_partition_name(norm_name_buff, path,
part_elem->partition_name,
NORMAL_PART_NAME, TRUE)))
error= ret_error;
DBUG_PRINT("info", ("Delete partition %s", norm_name_buff));
if ((ret_error= file->ha_delete_table(norm_name_buff)))
error= ret_error;
@@ -825,10 +833,12 @@ int ha_partition::rename_partitions(const char *path)
{
sub_elem= sub_it++;
part= i * num_subparts + j;
create_subpartition_name(norm_name_buff, path,
part_elem->partition_name,
sub_elem->partition_name,
NORMAL_PART_NAME);
if ((ret_error= create_subpartition_name(norm_name_buff, path,
part_elem->partition_name,
sub_elem->partition_name,
NORMAL_PART_NAME)))
error= ret_error;
if (part_elem->part_state == PART_IS_CHANGED)
{
file= m_reorged_file[part_count++];
@@ -840,10 +850,12 @@ int ha_partition::rename_partitions(const char *path)
(void) sync_ddl_log();
}
file= m_new_file[part];
create_subpartition_name(part_name_buff, path,
part_elem->partition_name,
sub_elem->partition_name,
TEMP_PART_NAME);
if ((ret_error= create_subpartition_name(part_name_buff, path,
part_elem->partition_name,
sub_elem->partition_name,
TEMP_PART_NAME)))
error= ret_error;
DBUG_PRINT("info", ("Rename subpartition from %s to %s",
part_name_buff, norm_name_buff));
if ((ret_error= file->ha_rename_table(part_name_buff,
@@ -857,9 +869,11 @@ int ha_partition::rename_partitions(const char *path)
}
else
{
create_partition_name(norm_name_buff, path,
part_elem->partition_name, NORMAL_PART_NAME,
TRUE);
if ((ret_error= create_partition_name(norm_name_buff, path,
part_elem->partition_name,
NORMAL_PART_NAME, TRUE)))
error= ret_error;
if (part_elem->part_state == PART_IS_CHANGED)
{
file= m_reorged_file[part_count++];
@@ -871,9 +885,11 @@ int ha_partition::rename_partitions(const char *path)
(void) sync_ddl_log();
}
file= m_new_file[i];
create_partition_name(part_name_buff, path,
part_elem->partition_name, TEMP_PART_NAME,
TRUE);
if ((ret_error= create_partition_name(part_name_buff, path,
part_elem->partition_name,
TEMP_PART_NAME, TRUE)))
error= ret_error;
DBUG_PRINT("info", ("Rename partition from %s to %s",
part_name_buff, norm_name_buff));
if ((ret_error= file->ha_rename_table(part_name_buff,
@@ -1477,7 +1493,7 @@ int ha_partition::change_partitions(HA_CREATE_INFO *create_info,
{
List_iterator<partition_element> part_it(m_part_info->partitions);
List_iterator <partition_element> t_it(m_part_info->temp_partitions);
char part_name_buff[FN_REFLEN];
char part_name_buff[FN_REFLEN + 1];
uint num_parts= m_part_info->partitions.elements;
uint num_subparts= m_part_info->num_subparts;
uint i= 0;
@@ -1687,10 +1703,15 @@ int ha_partition::change_partitions(HA_CREATE_INFO *create_info,
do
{
partition_element *sub_elem= sub_it++;
create_subpartition_name(part_name_buff, path,
part_elem->partition_name,
sub_elem->partition_name,
name_variant);
if ((error= create_subpartition_name(part_name_buff, path,
part_elem->partition_name,
sub_elem->partition_name,
name_variant)))
{
cleanup_new_partition(part_count);
DBUG_RETURN(error);
}
part= i * num_subparts + j;
DBUG_PRINT("info", ("Add subpartition %s", part_name_buff));
if ((error= prepare_new_partition(table, create_info,
@@ -1708,9 +1729,14 @@ int ha_partition::change_partitions(HA_CREATE_INFO *create_info,
}
else
{
create_partition_name(part_name_buff, path,
part_elem->partition_name, name_variant,
TRUE);
if ((error= create_partition_name(part_name_buff, path,
part_elem->partition_name,
name_variant, TRUE)))
{
cleanup_new_partition(part_count);
DBUG_RETURN(error);
}
DBUG_PRINT("info", ("Add partition %s", part_name_buff));
if ((error= prepare_new_partition(table, create_info,
new_file_array[i],
@@ -1967,8 +1993,8 @@ int ha_partition::del_ren_cre_table(const char *from,
{
int save_error= 0;
int error= HA_ERR_INTERNAL_ERROR;
char from_buff[FN_REFLEN], to_buff[FN_REFLEN], from_lc_buff[FN_REFLEN],
to_lc_buff[FN_REFLEN], buff[FN_REFLEN];
char from_buff[FN_REFLEN + 1], to_buff[FN_REFLEN + 1], from_lc_buff[FN_REFLEN + 1],
to_lc_buff[FN_REFLEN + 1], buff[FN_REFLEN + 1];
char *name_buffer_ptr;
const char *from_path;
const char *to_path= NULL;
@@ -2015,13 +2041,16 @@ int ha_partition::del_ren_cre_table(const char *from,
i= 0;
do
{
create_partition_name(from_buff, from_path, name_buffer_ptr,
NORMAL_PART_NAME, FALSE);
if ((error= create_partition_name(from_buff, from_path, name_buffer_ptr,
NORMAL_PART_NAME, FALSE)))
DBUG_RETURN(error);
if (to != NULL)
{ // Rename branch
create_partition_name(to_buff, to_path, name_buffer_ptr,
NORMAL_PART_NAME, FALSE);
if ((error= create_partition_name(to_buff, to_path, name_buffer_ptr,
NORMAL_PART_NAME, FALSE)))
DBUG_RETURN(error);
error= (*file)->ha_rename_table(from_buff, to_buff);
if (error)
goto rename_error;
@@ -2066,9 +2095,9 @@ int ha_partition::del_ren_cre_table(const char *from,
name_buffer_ptr= m_name_buffer_ptr;
for (abort_file= file, file= m_file; file < abort_file; file++)
{
create_partition_name(from_buff, from_path, name_buffer_ptr, NORMAL_PART_NAME,
FALSE);
(void) (*file)->ha_delete_table((const char*) from_buff);
if (!create_partition_name(from_buff, from_path, name_buffer_ptr, NORMAL_PART_NAME,
FALSE))
(void) (*file)->ha_delete_table((const char*) from_buff);
name_buffer_ptr= strend(name_buffer_ptr) + 1;
}
DBUG_RETURN(error);
@@ -2077,12 +2106,12 @@ int ha_partition::del_ren_cre_table(const char *from,
for (abort_file= file, file= m_file; file < abort_file; file++)
{
/* Revert the rename, back from 'to' to the original 'from' */
create_partition_name(from_buff, from_path, name_buffer_ptr,
NORMAL_PART_NAME, FALSE);
create_partition_name(to_buff, to_path, name_buffer_ptr,
NORMAL_PART_NAME, FALSE);
/* Ignore error here */
(void) (*file)->ha_rename_table(to_buff, from_buff);
if (!create_partition_name(from_buff, from_path, name_buffer_ptr,
NORMAL_PART_NAME, FALSE))
if (!create_partition_name(to_buff, to_path, name_buffer_ptr,
NORMAL_PART_NAME, FALSE))
/* Ignore error here */
(void) (*file)->ha_rename_table(to_buff, from_buff);
name_buffer_ptr= strend(name_buffer_ptr) + 1;
}
DBUG_RETURN(error);
@@ -2707,7 +2736,7 @@ int ha_partition::open(const char *name, int mode, uint test_if_locked)
char *name_buffer_ptr;
int error= HA_ERR_INITIALIZATION;
handler **file;
char name_buff[FN_REFLEN];
char name_buff[FN_REFLEN + 1];
bool is_not_tmp_table= (table_share->tmp_table == NO_TMP_TABLE);
ulonglong check_table_flags;
DBUG_ENTER("ha_partition::open");
@@ -2777,8 +2806,10 @@ int ha_partition::open(const char *name, int mode, uint test_if_locked)
file= m_is_clone_of->m_file;
for (i= 0; i < m_tot_parts; i++)
{
create_partition_name(name_buff, name, name_buffer_ptr, NORMAL_PART_NAME,
FALSE);
if ((error= create_partition_name(name_buff, name, name_buffer_ptr,
NORMAL_PART_NAME, FALSE)))
goto err_handler;
if (!(m_file[i]= file[i]->clone(name_buff, m_clone_mem_root)))
{
error= HA_ERR_INITIALIZATION;
@@ -2793,8 +2824,9 @@ int ha_partition::open(const char *name, int mode, uint test_if_locked)
file= m_file;
do
{
create_partition_name(name_buff, name, name_buffer_ptr, NORMAL_PART_NAME,
FALSE);
if ((error= create_partition_name(name_buff, name, name_buffer_ptr,
NORMAL_PART_NAME, FALSE)))
goto err_handler;
if ((error= (*file)->ha_open(table, name_buff, mode, test_if_locked)))
goto err_handler;
m_num_locks+= (*file)->lock_count();
Oops, something went wrong.

0 comments on commit be901b6

Please sign in to comment.