Details
-
Bug
-
Status: Confirmed (View Workflow)
-
Major
-
Resolution: Unresolved
-
10.6, 10.11, 11.4, 11.8, 12.3, 12.3.1
-
None
Description
ASAN error in recursive CTE with nested WITH, self-reference, and scalar subquery predicate (MariaDB 12.3.1)
Summary
A new crash candidate was found while fuzzing and mutating queries around the MDEV-32308 bug family (error-path handling of recursive CTEs and partially constructed internal state).
The issue is reproducible on an ASAN debug build of MariaDB 12.3.1 and aborts with:
- Assertion m_alloced_field_count failed
- Crash path reaches Create_tmp_table::start() during derived/CTE preparation
Reproducer SQL
CREATE DATABASE IF NOT EXISTS test; |
USE test; |
DROP TABLE IF EXISTS t14; |
CREATE TABLE t14(a INT); |
INSERT INTO t14 VALUES (1),(2); |
 |
WITH RECURSIVE x(a) AS |
(WITH y(a) AS (SELECT a FROM z) SELECT y.a FROM y, y y2), |
z(a) AS |
(SELECT 1 UNION SELECT a FROM x) |
SELECT x FROM x WHERE (SELECT x FROM x); |
Actual Result (ASAN Debug Build)
Client side:
ERROR 2026 (HY000): TLS/SSL error: unexpected eof while reading
|
Server side (key log lines):
mariadbd: /public/home/rongyankai/mariadb-12.3.1/sql/sql_select.cc:22125:
|
TABLE* Create_tmp_table::start(THD*, TMP_TABLE_PARAM*, const LEX_CSTRING*):
|
Assertion `m_alloced_field_count' failed.
|
Backtrace excerpt:
sql/sql_select.cc:22126(Create_tmp_table::start(...))
|
sql/sql_select.cc:23027(create_tmp_table(...))
|
sql/sql_union.cc:355(select_unit::create_result_table(...))
|
sql/sql_derived.cc:715(mysql_derived_prepare(...))
|
sql/sql_derived.cc:203(mysql_handle_single_derived(...))
|
...
|
Query: WITH RECURSIVE x(a) AS (WITH y(a) AS (SELECT a FROM z) SELECT y.a FROM y, y y2),
|
z(a) AS (SELECT 1 UNION SELECT a FROM x)
|
SELECT x FROM x WHERE (SELECT x FROM x)
|
Expected Result
The server should return a regular SQL error without aborting/asserting, including on ASAN/debug builds.
Source-Level Analysis
The abort happens because Create_tmp_table::start() assumes a non-zero computed field count:
m_alloced_field_count= param->field_count + param->func_count + param->sum_func_count;
|
DBUG_ASSERT(m_alloced_field_count);
|
From the stack, this is reached via recursive CTE / derived preparation:
- mysql_derived_prepare() -> create_result_table() -> Create_tmp_table::start()
This suggests an error-path state inconsistency where tmp-table metadata (field accounting) is not valid but is still consumed by the tmp-table creation path.
Attachments
Issue Links
- relates to
-
MDEV-32427 Segmentation fault at /mariadb-11.3.0/sql/table.cc:7154
-
- Confirmed
-
-
MDEV-37093 LeakSanitizer: detected memory leaks on PREPARE with WITH RECURSIVE
-
- Confirmed
-
-
MDEV-32308 Server crash on cleanup of non-fully-constructed-due-to-an-error CTE
-
- Closed
-