summaryrefslogtreecommitdiff
path: root/client/mysqlcheck.c
diff options
context:
space:
mode:
authorShishir Jaiswal <shishir.j.jaiswal@oracle.com>2016-05-16 13:46:49 +0530
committerShishir Jaiswal <shishir.j.jaiswal@oracle.com>2016-05-16 13:46:49 +0530
commitcb2974156823977fd2c700c64ff0867183b3f744 (patch)
treef5703689109a6628955ca39bd559183ee4269b8d /client/mysqlcheck.c
parentdf7ecf64f5b9c6fb4b7789a414306de89b58bec7 (diff)
downloadmariadb-git-cb2974156823977fd2c700c64ff0867183b3f744.tar.gz
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
Diffstat (limited to 'client/mysqlcheck.c')
-rw-r--r--client/mysqlcheck.c42
1 files changed, 26 insertions, 16 deletions
diff --git a/client/mysqlcheck.c b/client/mysqlcheck.c
index a564e871281..55b941e7f1a 100644
--- a/client/mysqlcheck.c
+++ b/client/mysqlcheck.c
@@ -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");