mirror of
https://github.com/MariaDB/server.git
synced 2025-08-08 11:22:35 +03:00
Bug#21977380 - POSSIBLE BUFFER OVERFLOW ISSUES
DESCRIPTION =========== Buffer overflow is reported in a lot of code sections spanning across server, client programs, Regex libraries etc. If not handled appropriately, they can cause abnormal behaviour. ANALYSIS ======== The reported casea are the ones which are likely to result in SEGFAULT, MEMORY LEAK etc. FIX === - sprintf() has been replaced by my_snprintf() to avoid buffer overflow. - my_free() is done after checking if the pointer isn't NULL already and setting it to NULL thereafter at few places. - Buffer is ensured to be large enough to hold the data. - 'unsigned int' (aka 'uint') is replaced with 'size_t' to avoid wraparound. - Memory is freed (if not done so) after its alloced and used. - Inserted assert() for size check in InnoDb memcached code (from 5.6 onwards) - Other minor changes
This commit is contained in:
@@ -213,13 +213,13 @@ static int process_selected_tables(char *db, char **table_names, int tables);
|
||||
static int process_all_tables_in_db(char *database);
|
||||
static int process_one_db(char *database);
|
||||
static int use_db(char *database);
|
||||
static int handle_request_for_tables(char *tables, uint length);
|
||||
static int handle_request_for_tables(char *tables, size_t length);
|
||||
static int dbConnect(char *host, char *user,char *passwd);
|
||||
static void dbDisconnect(char *host);
|
||||
static void DBerror(MYSQL *mysql, const char *when);
|
||||
static void safe_exit(int error);
|
||||
static void print_result();
|
||||
static uint fixed_name_length(const char *name);
|
||||
static size_t fixed_name_length(const char *name);
|
||||
static char *fix_table_name(char *dest, char *src);
|
||||
int what_to_do = 0;
|
||||
|
||||
@@ -486,7 +486,7 @@ static int process_selected_tables(char *db, char **table_names, int tables)
|
||||
*end++= ',';
|
||||
}
|
||||
*--end = 0;
|
||||
handle_request_for_tables(table_names_comma_sep + 1, (uint) (tot_length - 1));
|
||||
handle_request_for_tables(table_names_comma_sep + 1, tot_length - 1);
|
||||
my_free(table_names_comma_sep);
|
||||
}
|
||||
else
|
||||
@@ -496,10 +496,10 @@ static int process_selected_tables(char *db, char **table_names, int tables)
|
||||
} /* process_selected_tables */
|
||||
|
||||
|
||||
static uint fixed_name_length(const char *name)
|
||||
static size_t fixed_name_length(const char *name)
|
||||
{
|
||||
const char *p;
|
||||
uint extra_length= 2; /* count the first/last backticks */
|
||||
size_t extra_length= 2; /* count the first/last backticks */
|
||||
|
||||
for (p= name; *p; p++)
|
||||
{
|
||||
@@ -508,7 +508,7 @@ static uint fixed_name_length(const char *name)
|
||||
else if (*p == '.')
|
||||
extra_length+= 2;
|
||||
}
|
||||
return (uint) ((p - name) + extra_length);
|
||||
return (size_t) ((p - name) + extra_length);
|
||||
}
|
||||
|
||||
|
||||
@@ -564,7 +564,7 @@ static int process_all_tables_in_db(char *database)
|
||||
*/
|
||||
|
||||
char *tables, *end;
|
||||
uint tot_length = 0;
|
||||
size_t tot_length = 0;
|
||||
|
||||
while ((row = mysql_fetch_row(res)))
|
||||
tot_length+= fixed_name_length(row[0]) + 2;
|
||||
@@ -622,7 +622,9 @@ static int fix_table_storage_name(const char *name)
|
||||
int rc= 0;
|
||||
if (strncmp(name, "#mysql50#", 9))
|
||||
return 1;
|
||||
sprintf(qbuf, "RENAME TABLE `%s` TO `%s`", name, name + 9);
|
||||
my_snprintf(qbuf, sizeof(qbuf), "RENAME TABLE `%s` TO `%s`",
|
||||
name, name + 9);
|
||||
|
||||
rc= run_query(qbuf);
|
||||
if (verbose)
|
||||
printf("%-50s %s\n", name, rc ? "FAILED" : "OK");
|
||||
@@ -635,7 +637,8 @@ static int fix_database_storage_name(const char *name)
|
||||
int rc= 0;
|
||||
if (strncmp(name, "#mysql50#", 9))
|
||||
return 1;
|
||||
sprintf(qbuf, "ALTER DATABASE `%s` UPGRADE DATA DIRECTORY NAME", name);
|
||||
my_snprintf(qbuf, sizeof(qbuf), "ALTER DATABASE `%s` UPGRADE DATA DIRECTORY "
|
||||
"NAME", name);
|
||||
rc= run_query(qbuf);
|
||||
if (verbose)
|
||||
printf("%-50s %s\n", name, rc ? "FAILED" : "OK");
|
||||
@@ -653,7 +656,7 @@ static int rebuild_table(char *name)
|
||||
ptr= strmov(query, "ALTER TABLE ");
|
||||
ptr= fix_table_name(ptr, name);
|
||||
ptr= strxmov(ptr, " FORCE", NullS);
|
||||
if (mysql_real_query(sock, query, (uint)(ptr - query)))
|
||||
if (mysql_real_query(sock, query, (ulong)(ptr - query)))
|
||||
{
|
||||
fprintf(stderr, "Failed to %s\n", query);
|
||||
fprintf(stderr, "Error: %s\n", mysql_error(sock));
|
||||
@@ -702,10 +705,10 @@ static int disable_binlog()
|
||||
return run_query(stmt);
|
||||
}
|
||||
|
||||
static int handle_request_for_tables(char *tables, uint length)
|
||||
static int handle_request_for_tables(char *tables, size_t length)
|
||||
{
|
||||
char *query, *end, options[100], message[100];
|
||||
uint query_length= 0;
|
||||
size_t query_length= 0, query_size= sizeof(char)*(length+110);
|
||||
const char *op = 0;
|
||||
|
||||
options[0] = 0;
|
||||
@@ -736,10 +739,14 @@ static int handle_request_for_tables(char *tables, uint length)
|
||||
return fix_table_storage_name(tables);
|
||||
}
|
||||
|
||||
if (!(query =(char *) my_malloc((sizeof(char)*(length+110)), MYF(MY_WME))))
|
||||
if (!(query =(char *) my_malloc(query_size, MYF(MY_WME))))
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
if (opt_all_in_1)
|
||||
{
|
||||
DBUG_ASSERT(strlen(op)+strlen(tables)+strlen(options)+8+1 <= query_size);
|
||||
|
||||
/* No backticks here as we added them before */
|
||||
query_length= sprintf(query, "%s TABLE %s %s", op, tables, options);
|
||||
}
|
||||
@@ -750,7 +757,7 @@ static int handle_request_for_tables(char *tables, uint length)
|
||||
ptr= strmov(strmov(query, op), " TABLE ");
|
||||
ptr= fix_table_name(ptr, tables);
|
||||
ptr= strxmov(ptr, " ", options, NullS);
|
||||
query_length= (uint) (ptr - query);
|
||||
query_length= (size_t) (ptr - query);
|
||||
}
|
||||
if (mysql_real_query(sock, query, query_length))
|
||||
{
|
||||
@@ -834,7 +841,10 @@ static void print_result()
|
||||
prev_alter[0]= 0;
|
||||
}
|
||||
else
|
||||
strcpy(prev_alter, alter_txt);
|
||||
{
|
||||
strncpy(prev_alter, alter_txt, MAX_ALTER_STR_SIZE-1);
|
||||
prev_alter[MAX_ALTER_STR_SIZE-1]= 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -978,7 +988,7 @@ int main(int argc, char **argv)
|
||||
process_databases(argv);
|
||||
if (opt_auto_repair)
|
||||
{
|
||||
uint i;
|
||||
size_t i;
|
||||
|
||||
if (!opt_silent && (tables4repair.elements || tables4rebuild.elements))
|
||||
puts("\nRepairing tables");
|
||||
|
Reference in New Issue
Block a user