summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergei Golubchik <serg@mariadb.org>2018-04-16 23:14:28 +0200
committerSergei Golubchik <serg@mariadb.org>2018-05-10 12:48:30 +0200
commit92a13148e80c30422ae5460032169cbe1946fa6d (patch)
treeea80b092ccfebfb9dea57530088caa3c5cb63d2b
parent88a0bb83dfa1746571c99503f1cfd586f63e9a17 (diff)
downloadmariadb-git-92a13148e80c30422ae5460032169cbe1946fa6d.tar.gz
MDEV-15746 ASAN heap-use-after-free in Item_change_list::rollback_item_tree_changes on ALTER executed as PS
don't try to convert a default value string from a user character set into a column character set, if this particular default value string did not came from the user at all (that is, if it's an ALTER TABLE and the default value string is the *old* default value of the unaltered column). This used to crash, because old defaults are allocated on the old table's memroot, which is freed mid-ALTER when the old table is closed. So thd->rollback_item_tree_changes() at the end of the ALTER was writing into the freed memory.
-rw-r--r--mysql-test/r/ps.result11
-rw-r--r--mysql-test/t/ps.test15
-rw-r--r--sql/sql_table.cc2
3 files changed, 28 insertions, 0 deletions
diff --git a/mysql-test/r/ps.result b/mysql-test/r/ps.result
index 84d705587e8..6f86b330251 100644
--- a/mysql-test/r/ps.result
+++ b/mysql-test/r/ps.result
@@ -5163,3 +5163,14 @@ END;
$$
CALL p1('x');
DROP PROCEDURE p1;
+create table t1 (b blob default '');
+prepare stmt from "alter table t1 force";
+execute stmt;
+execute stmt;
+execute stmt;
+set names latin1;
+prepare stmt from "alter table t1 modify b text character set utf8 default 'a'";
+execute stmt;
+execute stmt;
+execute stmt;
+drop table t1;
diff --git a/mysql-test/t/ps.test b/mysql-test/t/ps.test
index 565f831efdd..e051cdce179 100644
--- a/mysql-test/t/ps.test
+++ b/mysql-test/t/ps.test
@@ -4635,3 +4635,18 @@ DELIMITER ;$$
--disable_result_log
CALL p1('x');
DROP PROCEDURE p1;
+
+#
+# MDEV-15746 ASAN heap-use-after-free in Item_change_list::rollback_item_tree_changes on ALTER executed as PS
+#
+create table t1 (b blob default '');
+prepare stmt from "alter table t1 force";
+execute stmt;
+execute stmt;
+execute stmt;
+set names latin1;
+prepare stmt from "alter table t1 modify b text character set utf8 default 'a'";
+execute stmt;
+execute stmt;
+execute stmt;
+drop table t1;
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index 9e7973b745c..1ed2194b09a 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -3378,6 +3378,8 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
*/
if (sql_field->default_value &&
sql_field->default_value->expr->basic_const_item() &&
+ (!sql_field->field ||
+ sql_field->field->default_value != sql_field->default_value) &&
save_cs != sql_field->default_value->expr->collation.collation &&
(sql_field->sql_type == MYSQL_TYPE_VAR_STRING ||
sql_field->sql_type == MYSQL_TYPE_STRING ||