Skip to content

Commit 9af5e6b

Browse files
Avoid memory overruns when buffer_length is too small (when fetching binary data in prepared statements)
1 parent 7d4fd47 commit 9af5e6b

5 files changed

Lines changed: 160 additions & 145 deletions

File tree

include/errmsg.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ extern const char *client_errors[]; /* Error messages */
3030
#define CR_MAX_ERROR 2999
3131
#if defined(OS2) && defined(MYSQL_SERVER)
3232
#define CER(X) client_errors[(X)-CR_MIN_ERROR]
33-
#else
33+
#elif !defined(ER)
3434
#define ER(X) client_errors[(X)-CR_MIN_ERROR]
3535
#endif
3636
#define CLIENT_ERRMAP 2 /* Errormap used by my_error() */

libmysql/libmysql.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4500,6 +4500,7 @@ static void send_data_long(MYSQL_BIND *param, longlong value)
45004500
}
45014501
}
45024502

4503+
45034504
/* Convert Double to buffer types */
45044505
static void send_data_double(MYSQL_BIND *param, double value)
45054506
{
@@ -4589,7 +4590,8 @@ static void send_data_str(MYSQL_BIND *param, char *value, uint length)
45894590
*param->length= length;
45904591
length= min(length, param->buffer_length);
45914592
memcpy(buffer, value, length);
4592-
buffer[length]='\0';
4593+
if (length != param->buffer_length)
4594+
buffer[length]='\0';
45934595
}
45944596
}
45954597

@@ -4808,7 +4810,9 @@ static void fetch_result_str(MYSQL_BIND *param, uchar **row)
48084810
ulong length= net_field_length(row);
48094811
ulong copy_length= min(length, param->buffer_length);
48104812
memcpy(param->buffer, (char *)*row, copy_length);
4811-
*(param->buffer+copy_length)= '\0';
4813+
/* Add an end null if there is room in the buffer */
4814+
if (copy_length != param->buffer_length)
4815+
*(param->buffer+copy_length)= '\0';
48124816
*param->length= length; // return total length
48134817
*row+= length;
48144818
}

libmysqld/lib_sql.cc

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,16 +47,18 @@ static bool check_user(THD *thd, enum_server_command command,
4747
char * get_mysql_home(){ return mysql_home;};
4848
char * get_mysql_real_data_home(){ return mysql_real_data_home;};
4949

50-
my_bool simple_command(MYSQL *mysql,enum enum_server_command command, const char *arg,
51-
ulong length, my_bool skipp_check)
50+
my_bool simple_command(MYSQL *mysql,enum enum_server_command command,
51+
const char *arg,
52+
ulong length, my_bool skipp_check)
5253
{
5354
my_bool result= 1;
5455
THD *thd=(THD *) mysql->thd;
5556

5657
/* Check that we are calling the client functions in right order */
5758
if (mysql->status != MYSQL_STATUS_READY)
5859
{
59-
strmov(thd->net.last_error,ER(thd->net.last_errno=CR_COMMANDS_OUT_OF_SYNC));
60+
strmov(thd->net.last_error,
61+
ER(thd->net.last_errno=CR_COMMANDS_OUT_OF_SYNC));
6062
return 1;
6163
}
6264

@@ -199,7 +201,7 @@ int STDCALL mysql_server_init(int argc, char **argv, char **groups)
199201
if (!opt_mysql_tmpdir || !opt_mysql_tmpdir[0])
200202
opt_mysql_tmpdir=(char*) P_tmpdir; /* purecov: inspected */
201203

202-
if (init_thread_environement())
204+
if (init_thread_environment())
203205
{
204206
mysql_server_end();
205207
return 1;

0 commit comments

Comments
 (0)