1
0
mirror of https://github.com/MariaDB/server.git synced 2026-10-23 18:49:29 +03:00

MDEV-41496 OOB write with RPAD() crash and multi-byte charsets and uservar

item's charset is metadata, it's known at fix_fields and does not
change later. user variables can violate this invariant if they're
changed and used in the same query.

Let's always wrap such variables in Item_func_conv_charset()
to make sure the caller always gets the same fixed charset, no matter
what the actual variable value is.

Variables that aren't changed in the same query do not get this
unnecessary conversion.
This commit is contained in:
Sergei Golubchik
2026-10-17 00:44:57 +02:00
parent 476a23cca4
commit dbafa77cba
5 changed files with 64 additions and 3 deletions

View File

@@ -5696,4 +5696,34 @@ a b a b
1 1 1 1
2 3 NULL NULL
drop table t1;
#
# MDEV-41496 OOB write with RPAD() crash and multi-byte charsets
#
SET @p=_latin1'x';
SELECT LENGTH(RPAD(_latin1'a', 766, @p)) FROM DUAL
WHERE (@p := CONVERT(UNHEX('0034002d') USING ucs2)) IS NOT NULL;
LENGTH(RPAD(_latin1'a', 766, @p))
766
EXPLAIN EXTENDED SELECT LENGTH(RPAD(_latin1'a', 766, @p)) FROM DUAL
WHERE (@p := CONVERT(UNHEX('0034002d') USING ucs2)) IS NOT NULL;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used
Warnings:
Note 1003 select octet_length(rpad('a',766,convert(@`p` using ucs2))) AS `LENGTH(RPAD(_latin1'a', 766, @p))` where 1
EXPLAIN EXTENDED SELECT LENGTH(RPAD(_latin1'a', 766, @p)) FROM DUAL
WHERE (@p = CONVERT(UNHEX('0034002d') USING ucs2)) IS NOT NULL;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used
Warnings:
Note 1003 select octet_length(rpad('a',766,@`p`)) AS `LENGTH(RPAD(_latin1'a', 766, @p))` where 1
SET @p=_utf16'x';
SELECT LENGTH(RPAD(_utf16'a', 766, @p)) FROM DUAL
WHERE (@p := CONCAT(_latin1'ab', _latin1 0xD800, REPEAT(_latin1'z',1000))) IS NOT NULL;
LENGTH(RPAD(_utf16'a', 766, @p))
1532
SET @p= _utf8mb3'b';
SELECT HEX(CONCAT(_utf8mb3'a', @p)) FROM DUAL
WHERE (@p := _ucs2 0x00FF) IS NOT NULL;
HEX(CONCAT(_utf8mb3'a', @p))
61C3BF
# End of 10.11 tests

View File

@@ -2633,4 +2633,26 @@ insert t1 values (1,1),(2,3);
select * from t1 left join t1 t2 on (t1.a=t2.b) where quote(t2.b)>'';
drop table t1;
--echo #
--echo # MDEV-41496 OOB write with RPAD() crash and multi-byte charsets
--echo #
SET @p=_latin1'x';
SELECT LENGTH(RPAD(_latin1'a', 766, @p)) FROM DUAL
WHERE (@p := CONVERT(UNHEX('0034002d') USING ucs2)) IS NOT NULL;
# charset convertor if @p is assigned to, no convertor otherwise
EXPLAIN EXTENDED SELECT LENGTH(RPAD(_latin1'a', 766, @p)) FROM DUAL
WHERE (@p := CONVERT(UNHEX('0034002d') USING ucs2)) IS NOT NULL;
EXPLAIN EXTENDED SELECT LENGTH(RPAD(_latin1'a', 766, @p)) FROM DUAL
WHERE (@p = CONVERT(UNHEX('0034002d') USING ucs2)) IS NOT NULL;
SET @p=_utf16'x';
SELECT LENGTH(RPAD(_utf16'a', 766, @p)) FROM DUAL
WHERE (@p := CONCAT(_latin1'ab', _latin1 0xD800, REPEAT(_latin1'z',1000))) IS NOT NULL;
SET @p= _utf8mb3'b';
SELECT HEX(CONCAT(_utf8mb3'a', @p)) FROM DUAL
WHERE (@p := _ucs2 0x00FF) IS NOT NULL;
--echo # End of 10.11 tests

View File

@@ -5808,8 +5808,8 @@ CREATE TABLE t (f VARCHAR(8)) CHARACTER SET utf8;
INSERT INTO t VALUES ('foo'),('bar');
EXECUTE IMMEDIATE 'SELECT GROUP_CONCAT(@x) FROM t GROUP BY @x := f';
GROUP_CONCAT(@x)
0
0
bar
foo
DROP TABLE t;
#
# MDEV-15703: Crash in EXECUTE IMMEDIATE 'CREATE OR REPLACE TABLE t1 (a INT DEFAULT ?)' USING DEFAULT

View File

@@ -4721,6 +4721,14 @@ bool Item_func_user_var::check_vcol_func_processor(void *arg)
return mark_unsupported_function("@", name.str, arg, VCOL_NON_DETERMINISTIC);
}
Item *Item_func_user_var::safe_charset_converter(THD *thd, CHARSET_INFO *tocs)
{
if (const_item())
return Item::safe_charset_converter(thd, tocs);
/* always convert, ignore 'conv->safe' as we don't know the charset yet */
return new (thd->mem_root) Item_func_conv_charset(thd, this, tocs, 0);
}
#define extra_size sizeof(double)
user_var_entry *get_variable(HASH *hash, LEX_CSTRING *name,

View File

@@ -1,7 +1,7 @@
#ifndef ITEM_FUNC_INCLUDED
#define ITEM_FUNC_INCLUDED
/* Copyright (c) 2000, 2016, Oracle and/or its affiliates.
Copyright (c) 2009, 2021, MariaDB
Copyright (c) 2009, 2026, MariaDB plc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -3552,6 +3552,7 @@ public:
{
return type_handler()->Item_get_date_with_warn(thd, this, ltime, fuzzydate);
}
Item *safe_charset_converter(THD *thd, CHARSET_INFO *tocs) override;
};