#At file:///home/kgeorge/mysql/work/B47412-5.1-bugteam/ based on revid:joro@stripped
3152 Georgi Kodinov 2009-10-08
Bug #47412: Valgrind warnings / user can read uninitalized memory using
SP variables
A function call may end without throwing an error or without setting
the return value. This can happen when e.g. an error occurs while
calculating the return value.
Fixed by setting the return value to NULL before executing the function
body.
added:
mysql-test/r/sp-bugs.result
mysql-test/t/sp-bugs.test
modified:
sql/sp_head.cc
sql/sp_rcontext.cc
sql/sp_rcontext.h
=== added file 'mysql-test/r/sp-bugs.result'
--- a/mysql-test/r/sp-bugs.result 1970-01-01 00:00:00 +0000
+++ b/mysql-test/r/sp-bugs.result 2009-10-08 15:16:35 +0000
@@ -0,0 +1,47 @@
+#
+# Bug #47412: Valgrind warnings / user can read uninitalized memory
+# using SP variables
+#
+CREATE SCHEMA testdb;
+USE testdb;
+CREATE FUNCTION f2 () RETURNS INTEGER
+BEGIN
+DECLARE CONTINUE HANDLER FOR SQLSTATE '42000' SET @aux = 1;
+RETURN f_not_exists () ;
+END|
+CREATE PROCEDURE p3 ( arg1 VARCHAR(32) )
+BEGIN
+CALL p_not_exists ( );
+END|
+# should not return valgrind warnings
+CALL p3 ( f2 () );
+ERROR 42000: PROCEDURE testdb.p_not_exists does not exist
+DROP SCHEMA testdb;
+CREATE SCHEMA testdb;
+USE testdb;
+CREATE FUNCTION f2 () RETURNS INTEGER
+BEGIN
+DECLARE CONTINUE HANDLER FOR SQLSTATE '42000' SET @aux = 1;
+RETURN f_not_exists () ;
+END|
+CREATE PROCEDURE p3 ( arg2 INTEGER )
+BEGIN
+CALL p_not_exists ( );
+END|
+# should not return valgrind warnings
+CALL p3 ( f2 () );
+ERROR 42000: PROCEDURE testdb.p_not_exists does not exist
+DROP SCHEMA testdb;
+CREATE SCHEMA testdb;
+USE testdb;
+CREATE FUNCTION f2 () RETURNS INTEGER
+BEGIN
+DECLARE CONTINUE HANDLER FOR SQLSTATE '42000' SET @aux = 1;
+RETURN f_not_exists () ;
+END|
+# should not return valgrind warnings
+SELECT f2 ();
+f2 ()
+NULL
+DROP SCHEMA testdb;
+End of 5.1 tests
=== added file 'mysql-test/t/sp-bugs.test'
--- a/mysql-test/t/sp-bugs.test 1970-01-01 00:00:00 +0000
+++ b/mysql-test/t/sp-bugs.test 2009-10-08 15:16:35 +0000
@@ -0,0 +1,61 @@
+# Test file for stored procedure bugfixes
+
+--echo #
+--echo # Bug #47412: Valgrind warnings / user can read uninitalized memory
+--echo # using SP variables
+--echo #
+
+CREATE SCHEMA testdb;
+USE testdb;
+DELIMITER |;
+CREATE FUNCTION f2 () RETURNS INTEGER
+BEGIN
+ DECLARE CONTINUE HANDLER FOR SQLSTATE '42000' SET @aux = 1;
+ RETURN f_not_exists () ;
+END|
+CREATE PROCEDURE p3 ( arg1 VARCHAR(32) )
+BEGIN
+ CALL p_not_exists ( );
+END|
+DELIMITER ;|
+--echo # should not return valgrind warnings
+--error ER_SP_DOES_NOT_EXIST
+CALL p3 ( f2 () );
+
+DROP SCHEMA testdb;
+
+CREATE SCHEMA testdb;
+USE testdb;
+DELIMITER |;
+CREATE FUNCTION f2 () RETURNS INTEGER
+BEGIN
+ DECLARE CONTINUE HANDLER FOR SQLSTATE '42000' SET @aux = 1;
+ RETURN f_not_exists () ;
+END|
+CREATE PROCEDURE p3 ( arg2 INTEGER )
+BEGIN
+ CALL p_not_exists ( );
+END|
+DELIMITER ;|
+--echo # should not return valgrind warnings
+--error ER_SP_DOES_NOT_EXIST
+CALL p3 ( f2 () );
+
+DROP SCHEMA testdb;
+
+CREATE SCHEMA testdb;
+USE testdb;
+DELIMITER |;
+CREATE FUNCTION f2 () RETURNS INTEGER
+BEGIN
+ DECLARE CONTINUE HANDLER FOR SQLSTATE '42000' SET @aux = 1;
+ RETURN f_not_exists () ;
+END|
+DELIMITER ;|
+--echo # should not return valgrind warnings
+SELECT f2 ();
+
+DROP SCHEMA testdb;
+
+
+--echo End of 5.1 tests
=== modified file 'sql/sp_head.cc'
--- a/sql/sp_head.cc 2009-07-29 20:07:08 +0000
+++ b/sql/sp_head.cc 2009-10-08 15:16:35 +0000
@@ -1768,6 +1768,9 @@ sp_head::execute_function(THD *thd, Item
*/
thd->set_n_backup_active_arena(&call_arena, &backup_arena);
+ /* initialize the return value to NULL */
+ nctx->initialize_return_value();
+
err_status= execute(thd);
thd->restore_active_arena(&call_arena, &backup_arena);
=== modified file 'sql/sp_rcontext.cc'
--- a/sql/sp_rcontext.cc 2008-01-23 22:36:57 +0000
+++ b/sql/sp_rcontext.cc 2009-10-08 15:16:35 +0000
@@ -162,6 +162,24 @@ sp_rcontext::set_return_value(THD *thd,
}
+/**
+ Initialize a function's return value
+
+ Set the return value of a function to NULL. This is the default
+ when the function fails to return a value due to e.g. exception
+ thrown in calculating the return value.
+*/
+
+void
+sp_rcontext::initialize_return_value()
+{
+ DBUG_ASSERT(m_return_value_fld);
+
+ m_return_value_fld->set_null();
+}
+
+
+
#define IS_WARNING_CONDITION(S) ((S)[0] == '0' && (S)[1] == '1')
#define IS_NOT_FOUND_CONDITION(S) ((S)[0] == '0' && (S)[1] == '2')
#define IS_EXCEPTION_CONDITION(S) ((S)[0] != '0' || (S)[1] > '2')
=== modified file 'sql/sp_rcontext.h'
--- a/sql/sp_rcontext.h 2008-01-23 20:26:41 +0000
+++ b/sql/sp_rcontext.h 2009-10-08 15:16:35 +0000
@@ -101,6 +101,8 @@ class sp_rcontext : public Sql_alloc
bool
set_return_value(THD *thd, Item **return_value_item);
+ void initialize_return_value();
+
inline bool
is_return_value_set() const
{
Attachment: [text/bzr-bundle] bzr/joro@sun.com-20091008151635-wdq2p3ptkmurusnu.bundle