summaryrefslogtreecommitdiff
path: root/client
diff options
context:
space:
mode:
authorcmiller@zippy.cornsilk.net <>2008-01-25 10:53:21 -0500
committercmiller@zippy.cornsilk.net <>2008-01-25 10:53:21 -0500
commitb040a97c2a518cda5d7d36a96797e6ac7e3524e7 (patch)
tree9989ebc512a8bb115bda888982f811ce30d12a88 /client
parent289d3e824d9d16c2596314dd11a43b65ab4e3abd (diff)
downloadmariadb-git-b040a97c2a518cda5d7d36a96797e6ac7e3524e7.tar.gz
Bug#33841: mysql client crashes when returning results for long-\
running queries Bug#33976: buffer overflow of variable time_buff in function com_go() An internal buffer was too short. Overextending could smash the stack on some architectures and cause SEGVs. This is not a problem that could be exploited to run arbitrary code. To fix, I expanded one buffer to cover all the size that could be written to (we know the abolute max).
Diffstat (limited to 'client')
-rw-r--r--client/mysql.cc19
1 files changed, 15 insertions, 4 deletions
diff --git a/client/mysql.cc b/client/mysql.cc
index d8810ba3c28..e4002822fcc 100644
--- a/client/mysql.cc
+++ b/client/mysql.cc
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000-2003 MySQL AB
+/* Copyright (C) 2000-2008 MySQL AB
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
@@ -729,7 +729,7 @@ static void usage(int version)
if (version)
return;
printf("\
-Copyright (C) 2002 MySQL AB\n\
+Copyright (C) 2000-2008 MySQL AB\n\
This software comes with ABSOLUTELY NO WARRANTY. This is free software,\n\
and you are welcome to modify and redistribute it under the GPL license\n");
printf("Usage: %s [OPTIONS] [database]\n", my_progname);
@@ -1910,7 +1910,8 @@ com_charset(String *buffer __attribute__((unused)), char *line)
static int
com_go(String *buffer,char *line __attribute__((unused)))
{
- char buff[200], time_buff[32], *pos;
+ char buff[200]; /* about 110 chars used so far */
+ char time_buff[52+3+1]; /* time max + space&parens + NUL */
MYSQL_RES *result;
ulong timer, warnings;
uint error= 0;
@@ -1973,6 +1974,8 @@ com_go(String *buffer,char *line __attribute__((unused)))
do
{
+ char *pos;
+
if (quick)
{
if (!(result=mysql_use_result(&mysql)) && mysql_field_count(&mysql))
@@ -1988,7 +1991,9 @@ com_go(String *buffer,char *line __attribute__((unused)))
if (verbose >= 3 || !opt_silent)
mysql_end_timer(timer,time_buff);
else
- time_buff[0]=0;
+ time_buff[0]= '\0';
+
+ /* Every branch must truncate buff . */
if (result)
{
if (!mysql_num_rows(result) && ! quick)
@@ -2045,6 +2050,7 @@ com_go(String *buffer,char *line __attribute__((unused)))
fflush(stdout);
mysql_free_result(result);
} while (!(err= mysql_next_result(&mysql)));
+
if (err >= 1)
error= put_error(&mysql);
@@ -3275,6 +3281,11 @@ static ulong start_timer(void)
}
+/**
+ Write as many as 52+1 bytes to buff, in the form of a legible duration of time.
+
+ len("4294967296 days, 23 hours, 59 minutes, 60.00 seconds") -> 52
+*/
static void nice_time(double sec,char *buff,bool part_second)
{
ulong tmp;