Skip to content

Commit ac11d3e

Browse files
MDEV-35816 ASAN use-after-poison in st_select_lex::print
Semi-joins with CTEs as the derived table will leave dangling pointers to the JOIN instance, from the corresponding SELECT_LEX instance, after first execution has completed. Clean these up during statement reinitialization, before subsequent executions occur.
1 parent 00fa5b8 commit ac11d3e

File tree

1 file changed

+29
-0
lines changed

1 file changed

+29
-0
lines changed

sql/sql_prepare.cc

+29
Original file line numberDiff line numberDiff line change
@@ -3134,6 +3134,33 @@ void mysql_sql_stmt_execute_immediate(THD *thd)
31343134
}
31353135

31363136

3137+
/**
3138+
Cleanup destroyed JOIN instances from derived tables' SELECT_LEX instances
3139+
before second execution by setting the SELECT_LEX instance's JOIN pointer
3140+
to nullptr.
3141+
*/
3142+
static void cleanup_joins(SELECT_LEX *sl)
3143+
{
3144+
TABLE_LIST *tl;
3145+
for (tl= sl->table_list.first; tl; tl= tl->next_local)
3146+
{
3147+
// Must be a derived view without a recursive table reference.
3148+
if (!tl->is_view_or_derived() || tl->is_with_table_recursive_reference())
3149+
continue;
3150+
3151+
SELECT_LEX_UNIT *unit= tl->get_unit();
3152+
if (!unit)
3153+
continue;
3154+
3155+
// For each query on the unit, disassociate the JOIN instance. It
3156+
// should have already been destroyed by this point. There's no way
3157+
// to assert that because it will result in EXC_BAD_ACCESS.
3158+
for (SELECT_LEX *sl= unit->first_select(); sl; sl= sl->next_select())
3159+
sl->join= nullptr;
3160+
}
3161+
}
3162+
3163+
31373164
/**
31383165
Reinit prepared statement/stored procedure before execution.
31393166
@@ -3238,6 +3265,8 @@ void reinit_stmt_before_use(THD *thd, LEX *lex)
32383265
}
32393266
if (sl->changed_elements & TOUCHED_SEL_DERIVED)
32403267
{
3268+
cleanup_joins(sl);
3269+
32413270
#ifdef DBUG_ASSERT_EXISTS
32423271
bool res=
32433272
#endif

0 commit comments

Comments
 (0)