[MDEV-26263] Investigate possible race on vc_templ recreation Created: 2021-07-28  Updated: 2024-01-23

Status: Open
Project: MariaDB Server
Component/s: None
Affects Version/s: 10.2, 10.3, 10.4, 10.5, 10.6
Fix Version/s: 10.4, 10.5, 10.6

Type: Bug Priority: Major
Reporter: Nikita Malyavin Assignee: Nikita Malyavin
Resolution: Unresolved Votes: 0
Labels: None

Issue Links:
Relates
relates to MDEV-33260 Crash at startup when unclean shutdown Open
relates to MDEV-20154 Assertion `len <= col->len || ((col->... Closed

 Description   

In ha_innobase::inplace_alter_table:

	rebuild_templ
	     = ctx->need_rebuild()
	       || ((ha_alter_info->handler_flags
		& ALTER_COLUMN_EQUAL_PACK_LENGTH)
		&& alter_templ_needs_rebuild(
		   altered_table, ha_alter_info, ctx->new_table));
 
	if ((ctx->new_table->n_v_cols > 0) && rebuild_templ) {
		/* Save the templ if isn't NULL so as to restore the
		original state in case of alter operation failures. */
		if (ctx->new_table->vc_templ != NULL && !ctx->need_rebuild()) {
			old_templ = ctx->new_table->vc_templ;
		}
		s_templ = UT_NEW_NOKEY(dict_vcol_templ_t());
 
		innobase_build_v_templ(
			altered_table, ctx->new_table, s_templ, NULL, false);
 
		ctx->new_table->vc_templ = s_templ;
	}

inplace_alter_table can be done without any locks, so race condition is possible here in case of !ctx->need_rebuild().

Idea: remove old_templ = ctx->new_table->vc_templ; and see what fails. Then construct a race test.

The deinitalixation part looks also unsafe:

	if (s_templ) {
		ut_ad(ctx->need_rebuild() || ctx->num_to_add_vcol > 0
		      || rebuild_templ);
		dict_free_vc_templ(s_templ);
		UT_DELETE(s_templ);
 
		ctx->new_table->vc_templ = old_templ;
	}

Access-after-free looks very likely here.


Generated at Thu Feb 08 09:43:58 UTC 2024 using Jira 8.20.16#820016-sha1:9d11dbea5f4be3d4cc21f03a88dd11d8c8687422.