Details
-
Bug
-
Status: Confirmed (View Workflow)
-
Critical
-
Resolution: Unresolved
-
10.11, 11.4, 11.8, 12.3, 11.8.8
-
Can result in hang or crash
Description
Root cause:
1. Named dynamic-column format serializes the aggregate names-pool size and
every name offset in two bytes.
2. `check_limit_named()` validates only each individual name against
`MAX_NAME_LENGTH`; `calc_var_sizes()` accumulates all names in `size_t`
without enforcing `MAX_TOTAL_NAME_LENGTH` (65,535).
3. `set_fixed_header_named()` truncates the aggregate with
`int2store(str->str + 3, hdr->nmpool_size)`.
4. `put_header_entry_named()` truncates each offset with `int2store()` and has
only a Debug assertion that the offset is below 65,536.
5. Seven individually valid 10,923-byte names put the seventh start offset at
65,538. Debug aborts at the assertion. Release stores wrapped size/offsets
and returns success with a malformed blob.
6. A fresh reader sees the wrapped name-pool size, so `COLUMN_CHECK` returns 0
and `COLUMN_LIST`/`COLUMN_JSON` reject the object with error 1919.
Crash:
Thread pointer: 0x77e92c000dc8
stacmariadbd(_Z11mysql_parseP3THDPcjP12Parser_state+0x680)[0x55d187d8bdb0]
/home/mysql/mariadb/bld/sql/mariadbd(_Z16dispatch_command19enum_server_commandP3THDPcjb+0x24ea)[0x55d187d8677a]
/home/mysql/mariadb/bld/sql/mariadbd(_Z10do_commandP3THDb+0xec9)[0x55d187d8d4a9]
/home/mysql/mariadb/bld/sql/mariadbd(_Z24do_handle_one_connectionP7CONNECTb+0x3da)[0x55d188110eda]
/home/mysql/mariadb/bld/sql/mariadbd(handle_one_connection+0x1ed)[0x55d1881109ed]
/home/mysql/mariadb/bld/sql/mariadbd(+0x1743346)[0x55d188a3d346]
nptl/pthread_create.c:442(start_thread)[0x7fe96cf65ac3]
x86_64/clone.S:102(_GI__clone)[0x7fe96cff6a84]
k_bottom = 0x7fe9562f9000 thread_stack 0x49000
addr2line: DWARF error: invalid or unhandled FORM value: 0x23
/home/mysql/mariadb/bld/sql/mariadbd(my_print_stacktrace+0x53)[0x55d1893e6f43]
/home/mysql/mariadb/bld/sql/mariadbd(handle_fatal_signal+0x2df)[0x55d18848288f]
libc_sigaction.c:0(__restore_rt)[0x7fe96cf13520]
nptl/pthread_kill.c:44(__pthread_kill_implementation)[0x7fe96cf679fc]
posix/raise.c:27(__GI_raise)[0x7fe96cf13476]
stdlib/abort.c:81(__GI_abort)[0x7fe96cef97f3]
intl/loadmsgcat.c:1177(_nl_load_domain)[0x7fe96cef971b]
/lib/x86_64-linux-gnu/libc.so.6(+0x39e96)[0x7fe96cf0ae96]
addr2line: DWARF error: invalid or unhandled FORM value: 0x23
ma_dyncol.c:0(put_header_entry_named)[0x55d1894101c6]
ma_dyncol.c:0(dynamic_column_create_many_internal_fmt)[0x55d1894048c6]
/home/mysql/mariadb/bld/sql/mariadbd(mariadb_dyncol_create_many_named+0x86)[0x55d189404bb6]
/home/mysql/mariadb/bld/sql/mariadbd(_ZN23Item_func_dyncol_create7val_strEP6String+0x1dc)[0x55d188644c5c]
/home/mysql/mariadb/bld/sql/mariadbd(_ZN22Item_func_set_user_var5checkEb+0x30d)[0x55d1885c9a1d]
/home/mysql/mariadb/bld/sql/mariadbd(_ZN12set_var_user5checkEP3THD+0x92)[0x55d187b62862]
/home/mysql/mariadb/bld/sql/mariadbd(_Z17sql_set_variablesP3THDP4ListI12set_var_baseEb+0x89)[0x55d187b618e9]
/home/mysql/mariadb/bld/sql/mariadbd(_Z21mysql_execute_commandP3THDb+0x8504)[0x55d187da1644]
/home/mysql/mariadb/bld/sql/
Connection ID (thread ID): 4
Status: NOT_KILLED
Query (0x77e92c048bf0): SET @trigger = COLUMN_CREATE(
CONCAT('a', REPEAT('x', 10922)), 1,
CONCAT('b', REPEAT('x', 10922)), 2,
CONCAT('c', REPEAT('x', 10922)), 3,
CONCAT('d', REPEAT('x', 10922)), 4,
CONCAT('e', REPEAT('x', 10922)), 5,
CONCAT('f', REPEAT('x', 10922)), 6,
CONCAT('g', REPEAT('x', 10922)), 7
)
Reproduce:
MariaDB 11.8.8-MariaDB-debug, source revision
46a8eb42a520193686d9a16d4cea4b3e002917e4
– MariaDB 11.8.8. No database, table, filesystem or administrative feature
– is required; both expressions are ordinary SELECT/SET expressions.
– 6 * 10,922 = 65,532 aggregate name bytes: valid control.
SET @control = COLUMN_CREATE(
CONCAT('a', REPEAT('x', 10921)), 1,
CONCAT('b', REPEAT('x', 10921)), 2,
CONCAT('c', REPEAT('x', 10921)), 3,
CONCAT('d', REPEAT('x', 10921)), 4,
CONCAT('e', REPEAT('x', 10921)), 5,
CONCAT('f', REPEAT('x', 10921)), 6
);
SELECT 'control', LENGTH(@control), COLUMN_CHECK(@control),
LENGTH(COLUMN_JSON(@control));
– 7 * 10,923 = 76,461 aggregate name bytes. Every individual name is below
– MAX_NAME_LENGTH, but the two-byte name-pool size/offset representation
– wraps. Debug builds abort while serializing the seventh entry. Release
– builds return a malformed 76,501-byte object.
SET @trigger = COLUMN_CREATE(
CONCAT('a', REPEAT('x', 10922)), 1,
CONCAT('b', REPEAT('x', 10922)), 2,
CONCAT('c', REPEAT('x', 10922)), 3,
CONCAT('d', REPEAT('x', 10922)), 4,
CONCAT('e', REPEAT('x', 10922)), 5,
CONCAT('f', REPEAT('x', 10922)), 6,
CONCAT('g', REPEAT('x', 10922)), 7
);
SELECT 'trigger_raw', LENGTH(@trigger), HEX(LEFT(@trigger, 16));
SELECT 'trigger_check', COLUMN_CHECK(@trigger);
SELECT 'trigger_list', COLUMN_LIST(@trigger);
SELECT 'trigger_json', LENGTH(COLUMN_JSON(@trigger));
Attachments
Issue Links
- relates to
-
MDEV-39667 ASAN: heap-buffer-overflow in dynamic_column_update_many_fmt during COLUMN_ADD
-
- Open
-