Skip to content

Commit 9a89733

Browse files
committed
MDEV-26420 Buffer overflow on instant ADD/DROP of generated column
prepare_inplace_add_virtual(): Over-estimate the size of the arrays by not subtracting table->s->virtual_fields (which may refer to stored, not virtual generated columns). InnoDB only distinguishes virtual columns.
1 parent 8911823 commit 9a89733

File tree

3 files changed

+22
-7
lines changed

3 files changed

+22
-7
lines changed

mysql-test/suite/innodb/r/instant_alter_bugs.result

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -458,3 +458,10 @@ f4 INT NOT NULL, f5 INT NOT NULL),
458458
CHANGE COLUMN f1 f1 CHAR(10) DEFAULT NULL;
459459
DROP TABLE t1;
460460
SET GLOBAL innodb_purge_rseg_truncate_frequency=@save_frequency;
461+
#
462+
# MDEV-26420 Buffer overflow on instant ADD/DROP of generated column
463+
#
464+
CREATE TABLE t1 (i int AS (0) STORED, j INT) ENGINE=InnoDB;
465+
ALTER TABLE t1 ADD COLUMN i INT GENERATED ALWAYS AS (1), DROP COLUMN i;
466+
DROP TABLE t1;
467+
# End of 10.4 tests

mysql-test/suite/innodb/t/instant_alter_bugs.test

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -476,3 +476,12 @@ ALTER TABLE t1 ADD COLUMN(f2 INT NOT NULL, f3 INT NOT NULL,
476476
CHANGE COLUMN f1 f1 CHAR(10) DEFAULT NULL;
477477
DROP TABLE t1;
478478
SET GLOBAL innodb_purge_rseg_truncate_frequency=@save_frequency;
479+
480+
--echo #
481+
--echo # MDEV-26420 Buffer overflow on instant ADD/DROP of generated column
482+
--echo #
483+
CREATE TABLE t1 (i int AS (0) STORED, j INT) ENGINE=InnoDB;
484+
ALTER TABLE t1 ADD COLUMN i INT GENERATED ALWAYS AS (1), DROP COLUMN i;
485+
DROP TABLE t1;
486+
487+
--echo # End of 10.4 tests

storage/innobase/handler/handler0alter.cc

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5016,20 +5016,18 @@ prepare_inplace_add_virtual(
50165016
{
50175017
ha_innobase_inplace_ctx* ctx;
50185018
ulint i = 0;
5019-
ulint j = 0;
50205019

50215020
ctx = static_cast<ha_innobase_inplace_ctx*>
50225021
(ha_alter_info->handler_ctx);
50235022

5024-
ctx->num_to_add_vcol = altered_table->s->virtual_fields
5025-
+ ctx->num_to_drop_vcol - table->s->virtual_fields;
5023+
ulint j = altered_table->s->virtual_fields + ctx->num_to_drop_vcol;
50265024

50275025
ctx->add_vcol = static_cast<dict_v_col_t*>(
5028-
mem_heap_zalloc(ctx->heap, ctx->num_to_add_vcol
5029-
* sizeof *ctx->add_vcol));
5026+
mem_heap_zalloc(ctx->heap, j * sizeof *ctx->add_vcol));
50305027
ctx->add_vcol_name = static_cast<const char**>(
5031-
mem_heap_alloc(ctx->heap, ctx->num_to_add_vcol
5032-
* sizeof *ctx->add_vcol_name));
5028+
mem_heap_alloc(ctx->heap, j * sizeof *ctx->add_vcol_name));
5029+
5030+
j = 0;
50335031

50345032
for (const Create_field& new_field :
50355033
ha_alter_info->alter_info->create_list) {
@@ -5110,6 +5108,7 @@ prepare_inplace_add_virtual(
51105108
j++;
51115109
}
51125110

5111+
ctx->num_to_add_vcol = j;
51135112
return(false);
51145113
}
51155114

0 commit comments

Comments
 (0)