From: Date: September 20 2008 10:51am Subject: bzr commit into mysql-5.1-bugteam branch (kpettersson:2677) Bug#38469 List-Archive: http://lists.mysql.com/commits/54404 X-Bug: 38469 Message-Id: <20080920085127.A671C530187@Adventure> MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit #At file:///home/thek/Development/cpp/mysqlbzr/mysql-5.0-bug38469/ 2677 Kristofer Pettersson 2008-09-20 Bug#38469 invalid memory read and/or crash with utf8 text field, stored procedure, uservar A stored procedure involving substrings could crash the server on certain platforms because of invalid memory reads. During storing the new blob-field value, the cached value's address range overlapped that of the new field value. This caused problems when the cached value storage was reallocated to provide access for a new characater set representation. The patch checks the address ranges, and if they overlap, the new field value is copied to a new storage before it is converted to the new character set. modified: mysql-test/r/sp.result mysql-test/t/sp.test sql/field.cc sql/field.h per-file messages: mysql-test/r/sp.result Added result set mysql-test/t/sp.test Added test case sql/field.cc The source and destination address ranges of a character conversion must not overlap or the 'from' address will be invalidated as the temporary value- object is re-allocated to fit the new character set. sql/field.h Added comments === modified file 'mysql-test/r/sp.result' --- a/mysql-test/r/sp.result 2008-08-20 09:49:28 +0000 +++ b/mysql-test/r/sp.result 2008-09-20 08:51:03 +0000 @@ -6662,6 +6662,16 @@ drop procedure p1; drop function f1; drop view v1; drop table t1; +drop procedure if exists `p2` $ +create procedure `p2`(in `a` text charset utf8) +begin +declare `pos` int default 1; +declare `str` text charset utf8; +set `str` := `a`; +select substr(`str`, `pos`+ 1 ) into `str`; +end $ +call `p2`('s s s s s s'); +drop procedure `p2`; # ------------------------------------------------------------------ # -- End of 5.0 tests # ------------------------------------------------------------------ === modified file 'mysql-test/t/sp.test' --- a/mysql-test/t/sp.test 2008-08-20 09:49:28 +0000 +++ b/mysql-test/t/sp.test 2008-09-20 08:51:03 +0000 @@ -7818,6 +7818,24 @@ drop function f1; drop view v1; drop table t1; +# +# Bug#38469 invalid memory read and/or crash with utf8 text field, stored procedure, uservar +# +delimiter $; +--disable_warnings +drop procedure if exists `p2` $ +--enable_warnings +create procedure `p2`(in `a` text charset utf8) +begin + declare `pos` int default 1; + declare `str` text charset utf8; + set `str` := `a`; + select substr(`str`, `pos`+ 1 ) into `str`; +end $ +delimiter ;$ +call `p2`('s s s s s s'); +drop procedure `p2`; + --echo # ------------------------------------------------------------------ --echo # -- End of 5.0 tests --echo # ------------------------------------------------------------------ === modified file 'sql/field.cc' --- a/sql/field.cc 2008-05-06 16:43:46 +0000 +++ b/sql/field.cc 2008-09-20 08:51:03 +0000 @@ -6992,8 +6992,18 @@ int Field_blob::store(const char *from,u return 0; } - if (from == value.ptr()) + /* + If the 'from' address is in the range of the temporary 'value'- + object we need to copy the content to a different location or it will be + invalidated when the 'value'-object is reallocated to make room for + the new character set. + */ + if (from >= value.ptr() && from <= value.ptr()+value.length()) { + /* + If content of the 'from'-address is cached in the 'value'-object + it is possible that the content needs a character conversion. + */ uint32 dummy_offset; if (!String::needs_conversion(length, cs, field_charset, &dummy_offset)) { === modified file 'sql/field.h' --- a/sql/field.h 2008-08-27 21:10:37 +0000 +++ b/sql/field.h 2008-09-20 08:51:03 +0000 @@ -1213,8 +1213,16 @@ public: class Field_blob :public Field_longstr { protected: + /** + The number of bytes used to represent the length of the blob. + */ uint packlength; - String value; // For temporaries + + /** + The 'value'-object is a cache fronting the storage engine. + */ + String value; + public: Field_blob(char *ptr_arg, uchar *null_ptr_arg, uchar null_bit_arg, enum utype unireg_check_arg, const char *field_name_arg,