summaryrefslogtreecommitdiff
path: root/sql/ha_partition.cc
diff options
context:
space:
mode:
authorNisha Gopalakrishnan <nisha.gopalakrishnan@oracle.com>2017-08-16 13:58:25 +0530
committerNisha Gopalakrishnan <nisha.gopalakrishnan@oracle.com>2017-08-23 12:59:38 +0530
commitbe901b60ae59c93848c829d1b0b2cb523ab8692e (patch)
tree21b144aebc7e58f48bda0ef9972b6a371c64f703 /sql/ha_partition.cc
parentebd96c314953f5c0073ff5846484fd5e438fe0ad (diff)
downloadmariadb-git-be901b60ae59c93848c829d1b0b2cb523ab8692e.tar.gz
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.
Diffstat (limited to 'sql/ha_partition.cc')
-rw-r--r--sql/ha_partition.cc150
1 files changed, 91 insertions, 59 deletions
diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc
index aadac36e2ee..414f9d52536 100644
--- a/sql/ha_partition.cc
+++ b/sql/ha_partition.cc
@@ -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 @@ create_error:
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 @@ rename_error:
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();