Commit 9af5e6b7 authored by monty@mashka.mysql.fi's avatar monty@mashka.mysql.fi

Avoid memory overruns when buffer_length is too small (when fetching binary...

Avoid memory overruns when buffer_length is too small (when fetching binary data in prepared statements)
parent 7d4fd474
...@@ -30,7 +30,7 @@ extern const char *client_errors[]; /* Error messages */ ...@@ -30,7 +30,7 @@ extern const char *client_errors[]; /* Error messages */
#define CR_MAX_ERROR 2999 #define CR_MAX_ERROR 2999
#if defined(OS2) && defined(MYSQL_SERVER) #if defined(OS2) && defined(MYSQL_SERVER)
#define CER(X) client_errors[(X)-CR_MIN_ERROR] #define CER(X) client_errors[(X)-CR_MIN_ERROR]
#else #elif !defined(ER)
#define ER(X) client_errors[(X)-CR_MIN_ERROR] #define ER(X) client_errors[(X)-CR_MIN_ERROR]
#endif #endif
#define CLIENT_ERRMAP 2 /* Errormap used by my_error() */ #define CLIENT_ERRMAP 2 /* Errormap used by my_error() */
......
...@@ -4500,6 +4500,7 @@ static void send_data_long(MYSQL_BIND *param, longlong value) ...@@ -4500,6 +4500,7 @@ static void send_data_long(MYSQL_BIND *param, longlong value)
} }
} }
/* Convert Double to buffer types */ /* Convert Double to buffer types */
static void send_data_double(MYSQL_BIND *param, double value) static void send_data_double(MYSQL_BIND *param, double value)
{ {
...@@ -4589,7 +4590,8 @@ static void send_data_str(MYSQL_BIND *param, char *value, uint length) ...@@ -4589,7 +4590,8 @@ static void send_data_str(MYSQL_BIND *param, char *value, uint length)
*param->length= length; *param->length= length;
length= min(length, param->buffer_length); length= min(length, param->buffer_length);
memcpy(buffer, value, length); memcpy(buffer, value, length);
buffer[length]='\0'; if (length != param->buffer_length)
buffer[length]='\0';
} }
} }
...@@ -4808,7 +4810,9 @@ static void fetch_result_str(MYSQL_BIND *param, uchar **row) ...@@ -4808,7 +4810,9 @@ static void fetch_result_str(MYSQL_BIND *param, uchar **row)
ulong length= net_field_length(row); ulong length= net_field_length(row);
ulong copy_length= min(length, param->buffer_length); ulong copy_length= min(length, param->buffer_length);
memcpy(param->buffer, (char *)*row, copy_length); memcpy(param->buffer, (char *)*row, copy_length);
*(param->buffer+copy_length)= '\0'; /* Add an end null if there is room in the buffer */
if (copy_length != param->buffer_length)
*(param->buffer+copy_length)= '\0';
*param->length= length; // return total length *param->length= length; // return total length
*row+= length; *row+= length;
} }
......
...@@ -47,8 +47,9 @@ static bool check_user(THD *thd, enum_server_command command, ...@@ -47,8 +47,9 @@ static bool check_user(THD *thd, enum_server_command command,
char * get_mysql_home(){ return mysql_home;}; char * get_mysql_home(){ return mysql_home;};
char * get_mysql_real_data_home(){ return mysql_real_data_home;}; char * get_mysql_real_data_home(){ return mysql_real_data_home;};
my_bool simple_command(MYSQL *mysql,enum enum_server_command command, const char *arg, my_bool simple_command(MYSQL *mysql,enum enum_server_command command,
ulong length, my_bool skipp_check) const char *arg,
ulong length, my_bool skipp_check)
{ {
my_bool result= 1; my_bool result= 1;
THD *thd=(THD *) mysql->thd; THD *thd=(THD *) mysql->thd;
...@@ -56,7 +57,8 @@ my_bool simple_command(MYSQL *mysql,enum enum_server_command command, const char ...@@ -56,7 +57,8 @@ my_bool simple_command(MYSQL *mysql,enum enum_server_command command, const char
/* Check that we are calling the client functions in right order */ /* Check that we are calling the client functions in right order */
if (mysql->status != MYSQL_STATUS_READY) if (mysql->status != MYSQL_STATUS_READY)
{ {
strmov(thd->net.last_error,ER(thd->net.last_errno=CR_COMMANDS_OUT_OF_SYNC)); strmov(thd->net.last_error,
ER(thd->net.last_errno=CR_COMMANDS_OUT_OF_SYNC));
return 1; return 1;
} }
...@@ -199,7 +201,7 @@ int STDCALL mysql_server_init(int argc, char **argv, char **groups) ...@@ -199,7 +201,7 @@ int STDCALL mysql_server_init(int argc, char **argv, char **groups)
if (!opt_mysql_tmpdir || !opt_mysql_tmpdir[0]) if (!opt_mysql_tmpdir || !opt_mysql_tmpdir[0])
opt_mysql_tmpdir=(char*) P_tmpdir; /* purecov: inspected */ opt_mysql_tmpdir=(char*) P_tmpdir; /* purecov: inspected */
if (init_thread_environement()) if (init_thread_environment())
{ {
mysql_server_end(); mysql_server_end();
return 1; return 1;
......
This diff is collapsed.
...@@ -1208,23 +1208,26 @@ bool dispatch_command(enum enum_server_command command, THD *thd, ...@@ -1208,23 +1208,26 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
while (!thd->fatal_error && thd->lex.found_colon) while (!thd->fatal_error && thd->lex.found_colon)
{ {
char *packet= thd->lex.found_colon;
/* /*
Multiple queries exits, execute them individually Multiple queries exits, execute them individually
*/ */
if (thd->lock || thd->open_tables || thd->derived_tables) if (thd->lock || thd->open_tables || thd->derived_tables)
close_thread_tables(thd); close_thread_tables(thd);
uint length= thd->query_length-(uint)(thd->lex.found_colon-thd->query); ulong length= thd->query_length-(ulong)(thd->lex.found_colon-thd->query);
/* Remove garbage at start of query */ /* Remove garbage at start of query */
char *packet= thd->lex.found_colon; while (my_isspace(system_charset_info, *packet) && length > 0)
while (my_isspace(system_charset_info,packet[0]) && length > 0)
{ {
packet++; packet++;
length--; length--;
} }
thd->query= packet;
thd->query_length= length; thd->query_length= length;
thd->query= packet;
VOID(pthread_mutex_lock(&LOCK_thread_count));
thd->query_id= query_id++;
VOID(pthread_mutex_unlock(&LOCK_thread_count));
mysql_parse(thd, packet, length); mysql_parse(thd, packet, length);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment