Commit 8db5274d authored by Monty's avatar Monty

MDEV-22703 DEFAULT() on a BLOB column can overwrite the default record

This can cause crashes when accessing already released memory

The issue was the Item_default created a internal field, pointing to
share->default_values, to be used with the DEFAULT() function.
This does not work for BLOB fields as these are freed at end of query.
Fixed by storing BLOB field data inside and area allocated by
Item_default_value,  like we do for nondeterministic default values.
parent da88e1ec
......@@ -3390,3 +3390,18 @@ ALTER TABLE t1 ADD b CHAR(255) DEFAULT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
ERROR 42S22: Unknown column 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' in 'DEFAULT'
DROP TABLE t1;
# end of 10.2 test
#
# MDEV-22703 DEFAULT() on a BLOB column can overwrite the default
# record, which can cause crashes when accessing already released
# memory.
#
CREATE TEMPORARY TABLE t1 (h POINT DEFAULT ST_GEOMFROMTEXT('Point(1 1)')) ENGINE=InnoDB;
INSERT INTO t1 () VALUES (),();
ALTER TABLE t1 FORCE;
SELECT DEFAULT(h) FROM t1;
SELECT length(DEFAULT(h)) FROM t1;
length(DEFAULT(h))
25
25
INSERT INTO t1 () VALUES ();
drop table t1;
--source include/have_innodb.inc
#
# test of already fixed bugs
#
......@@ -2107,5 +2109,20 @@ CREATE OR REPLACE TABLE t1(i int);
ALTER TABLE t1 ADD b CHAR(255) DEFAULT `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa`;
DROP TABLE t1;
--echo # end of 10.2 test
--echo #
--echo # MDEV-22703 DEFAULT() on a BLOB column can overwrite the default
--echo # record, which can cause crashes when accessing already released
--echo # memory.
--echo #
CREATE TEMPORARY TABLE t1 (h POINT DEFAULT ST_GEOMFROMTEXT('Point(1 1)')) ENGINE=InnoDB;
INSERT INTO t1 () VALUES (),();
ALTER TABLE t1 FORCE;
--disable_result_log
SELECT DEFAULT(h) FROM t1;
--enable_result_log
SELECT length(DEFAULT(h)) FROM t1;
INSERT INTO t1 () VALUES ();
drop table t1;
......@@ -9346,8 +9346,9 @@ bool Item_default_value::fix_fields(THD *thd, Item **items)
memcpy((void *)def_field, (void *)field_arg->field,
field_arg->field->size_of());
def_field->reset_fields();
// If non-constant default value expression
if (def_field->default_value && def_field->default_value->flags)
// If non-constant default value expression or a blob
if (def_field->default_value &&
(def_field->default_value->flags || def_field->flags & BLOB_FLAG))
{
uchar *newptr= (uchar*) thd->alloc(1+def_field->pack_length());
if (!newptr)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment