summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorunknown <gkodinov/kgeorge@magare.gmz>2007-06-12 11:02:34 +0300
committerunknown <gkodinov/kgeorge@magare.gmz>2007-06-12 11:02:34 +0300
commite164c08eafb005aa42da3fda2c97e374ee205c9b (patch)
tree9223ffd6e4d5568231707dea8a3ddc894efd7c7b
parent59d139eb293e1bcf72cf544e2b8dbe9216ee7acb (diff)
downloadmariadb-git-e164c08eafb005aa42da3fda2c97e374ee205c9b.tar.gz
Bug #28934: server crash when receiving malformed com_execute packets
Sometimes a parameter slot may not get a value because of the protocol data being plain wrong. Such cases should be detected and handled by returning an error. Fixed by checking data stream constraints where possible (like maximum length) and reacting to the case where a value cannot be constructed. sql/sql_prepare.cc: Bug #28934: - check for a parameter slot not being set because of wrong data - check if the length read from the stream is not greater than the maximum length of the field tests/mysql_client_test.c: Bug #28934: test case
-rw-r--r--sql/sql_prepare.cc10
-rw-r--r--tests/mysql_client_test.c83
2 files changed, 93 insertions, 0 deletions
diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc
index 42655608196..1453a377600 100644
--- a/sql/sql_prepare.cc
+++ b/sql/sql_prepare.cc
@@ -562,6 +562,8 @@ void set_param_date(Item_param *param, uchar **pos, ulong len)
static void set_param_str(Item_param *param, uchar **pos, ulong len)
{
ulong length= get_param_length(pos, len);
+ if (length > len)
+ length= len;
param->set_str((const char *)*pos, length);
*pos+= length;
}
@@ -731,6 +733,8 @@ static bool insert_params_withlog(Prepared_statement *stmt, uchar *null_array,
if (read_pos >= data_end)
DBUG_RETURN(1);
param->set_param_func(param, &read_pos, data_end - read_pos);
+ if (param->state == Item_param::NO_VALUE)
+ DBUG_RETURN(1);
}
}
res= param->query_val_str(&str);
@@ -767,6 +771,8 @@ static bool insert_params(Prepared_statement *stmt, uchar *null_array,
if (read_pos >= data_end)
DBUG_RETURN(1);
param->set_param_func(param, &read_pos, data_end - read_pos);
+ if (param->state == Item_param::NO_VALUE)
+ DBUG_RETURN(1);
}
}
if (param->convert_str_value(stmt->thd))
@@ -849,6 +855,8 @@ static bool emb_insert_params(Prepared_statement *stmt, String *expanded_query)
client_param->length ?
*client_param->length :
client_param->buffer_length);
+ if (param->state == Item_param::NO_VALUE)
+ DBUG_RETURN(1);
}
}
if (param->convert_str_value(thd))
@@ -890,6 +898,8 @@ static bool emb_insert_params_withlog(Prepared_statement *stmt, String *query)
client_param->length ?
*client_param->length :
client_param->buffer_length);
+ if (param->state == Item_param::NO_VALUE)
+ DBUG_RETURN(1);
}
}
res= param->query_val_str(&str);
diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c
index 54d29dbd683..7fc45b89b82 100644
--- a/tests/mysql_client_test.c
+++ b/tests/mysql_client_test.c
@@ -15687,6 +15687,88 @@ end:
/*
+ Bug#28934: server crash when receiving malformed com_execute packets
+*/
+
+static void test_bug28934()
+{
+ MYSQL *l_mysql;
+ my_bool error= 0;
+ my_ulonglong res;
+ MYSQL_BIND bind[5];
+ MYSQL_STMT *stmt;
+ int cnt;
+
+ if (!(l_mysql= mysql_init(NULL)))
+ {
+ myerror("mysql_init() failed");
+ DIE_UNLESS(1);
+ }
+ if (!(mysql_real_connect(l_mysql, opt_host, opt_user,
+ opt_password, current_db, opt_port,
+ opt_unix_socket, CLIENT_FOUND_ROWS)))
+ {
+ myerror("connection failed");
+ error= 1;
+ goto end;
+ }
+ l_mysql->reconnect= 1;
+ if (mysql_query(l_mysql, "drop table if exists t1"))
+ {
+ myerror(NULL);
+ error= 1;
+ goto end;
+ }
+ if (mysql_query(l_mysql, "create table t1(id int)"))
+ {
+ myerror(NULL);
+ error= 1;
+ goto end;
+ }
+ if (mysql_query(l_mysql, "insert into t1 values(1),(2),(3),(4),(5)"))
+ {
+ myerror(NULL);
+ error= 1;
+ goto end;
+ }
+ if (!(stmt= mysql_simple_prepare(l_mysql,
+ "select * from t1 where id in(?,?,?,?,?)")))
+ {
+ myerror(NULL);
+ error= 1;
+ goto end;
+ }
+
+ memset (&bind, 0, sizeof (bind));
+ for (cnt= 0; cnt < 5; cnt++)
+ {
+ bind[cnt].buffer_type= MYSQL_TYPE_LONG;
+ bind[cnt].buffer= (char*)&cnt;
+ bind[cnt].buffer_length= 0;
+ }
+ if(mysql_stmt_bind_param(stmt, bind))
+ {
+ myerror(NULL);
+ error= 1;
+ goto end;
+ }
+ stmt->param_count=2;
+ error= mysql_stmt_execute(stmt);
+ DIE_UNLESS (error != 0);
+ myerror(NULL);
+ error= 0;
+ if (mysql_query(l_mysql, "drop table t1"))
+ {
+ myerror(NULL);
+ error= 1;
+ }
+end:
+ mysql_close(l_mysql);
+ DIE_UNLESS(error == 0);
+}
+
+
+/*
Read and parse arguments and MySQL options from my.cnf
*/
@@ -15968,6 +16050,7 @@ static struct my_tests_st my_tests[]= {
{ "test_bug24179", test_bug24179 },
{ "test_bug27876", test_bug27876 },
{ "test_bug28505", test_bug28505 },
+ { "test_bug28934", test_bug28934 },
{ 0, 0 }
};