[MDEV-24041] Generated column DELETE with FOREIGN KEY crash InnoDB Created: 2020-10-27  Updated: 2021-07-23  Resolved: 2020-12-24

Status: Closed
Project: MariaDB Server
Component/s: Data Manipulation - Delete, Storage Engine - InnoDB
Affects Version/s: 10.2, 10.3, 10.4, 10.5
Fix Version/s: 10.2.37, 10.3.28, 10.4.18, 10.5.9

Type: Bug Priority: Critical
Reporter: Vicențiu Ciorbaru Assignee: Nikita Malyavin
Resolution: Fixed Votes: 0
Labels: ASAN

Issue Links:
Relates
relates to MDEV-26228 Heap-use-after-free on indexed virtua... Closed
relates to MDEV-25466 Merge new release of InnoDB 5.7.34 to... Closed

 Description   

Reported via HackerOne by Petr Gregor (gregy)

I discovered a sequence of sql commands which will crash mariadb server upon execution. I have replicated the problem with mariadb 10.5.6, mysql 8 and mysql 5.7 both in docker and when using a full VM. I am able to trigger the crash as a remote user with full access to a single database.

SQL to replicate the crash:

create database ctest;
use ctest;
 
DROP TABLE IF EXISTS `email_stats`;
DROP TABLE IF EXISTS `emails_metadata`;
DROP TABLE IF EXISTS `emails`;
 
CREATE TABLE `emails` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci ROW_FORMAT=DYNAMIC;
 
CREATE TABLE `email_stats` (
  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  `email_id` int(10) unsigned DEFAULT NULL,
  `date_sent` datetime NOT NULL,
  `generated_sent_date` date GENERATED ALWAYS AS (concat(year(`date_sent`),'-',lpad(month(`date_sent`),2,'0'),'-',lpad(dayofmonth(`date_sent`),2,'0'))) VIRTUAL,
  PRIMARY KEY (`id`),
  KEY `IDX_D0F71136A832C1C9` (`email_id`),
  KEY `mautic_generated_sent_date_email_id` (`generated_sent_date`,`email_id`),
  CONSTRAINT `FK_D0F71136A832C1C9` FOREIGN KEY (`email_id`) REFERENCES `emails` (`id`) ON DELETE SET NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci ROW_FORMAT=DYNAMIC;
 
CREATE TABLE `emails_metadata` (
  `email_id` int(10) unsigned NOT NULL,
  PRIMARY KEY (`email_id`),
  CONSTRAINT `FK_C79476FDA832C1C9` FOREIGN KEY (`email_id`) REFERENCES `emails` (`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci ROW_FORMAT=DYNAMIC;
 
 
INSERT INTO `emails` VALUES (1);
INSERT INTO `email_stats` (`id`, `email_id`,  `date_sent`) VALUES (1,1,'2020-10-22 13:32:41');
INSERT INTO `emails_metadata` VALUES (1);
 
COMMIT;
 
DELETE FROM emails;

The easiest way to replicate the problem is using these docker commands and pasting the above script into mysql shell:

docker run --rm  -e MYSQL_ALLOW_EMPTY_PASSWORD=yes --name mtest mariadb:latest &
docker exec -it mtest mysql

I do not have implementation level details about why this is happening. It is an accidental discovery.



 Comments   
Comment by Vicențiu Ciorbaru [ 2020-10-27 ]

From a discussion with marko

This is where the memory was freed, during the DELETE FROM emails:
#4  mem_heap_block_free (heap=<optimized out>, block=0x617000068618)
    at /mariadb/10.5m/storage/innobase/mem/mem0mem.cc:416
#5  0x00000000020bfe00 in mem_heap_free_heap_top (heap=0x612000057ad8, 
    old_top=0x612000057b58 "\276\276\276\276\276\276\276\276")
    at /mariadb/10.5m/storage/innobase/include/mem0mem.ic:259
#6  mem_heap_empty (heap=0x612000057ad8) at /mariadb/10.5m/storage/innobase/include/mem0mem.ic:290
#7  0x00000000020c1eae in row_upd_store_row (node=<optimized out>, thd=<optimized out>, 
    mysql_table=<optimized out>) at /mariadb/10.5m/storage/innobase/row/row0upd.cc:1892
#8  0x00000000020b4ef3 in row_upd_clust_step (node=0x617000068320, thr=0x6240000fc1a0)
    at /mariadb/10.5m/storage/innobase/row/row0upd.cc:2893
#9  row_upd (node=<optimized out>, thr=0x6240000fc1a0)
    at /mariadb/10.5m/storage/innobase/row/row0upd.cc:2992
#10 0x00000000020b334a in row_upd_step (thr=0x6240000fc1a0)
    at /mariadb/10.5m/storage/innobase/row/row0upd.cc:3136
#11 0x0000000001fe4f82 in row_update_cascade_for_mysql (thr=0x6240000fc1a0, node=<optimized out>, 
    table=<optimized out>) at /mariadb/10.5m/storage/innobase/row/row0mysql.cc:2213
#12 0x0000000001f756f7 in row_ins_foreign_check_on_constraint (thr=<optimized out>, 
    foreign=<optimized out>, pcur=<optimized out>, entry=<optimized out>, mtr=<optimized out>)
    at /mariadb/10.5m/storage/innobase/row/row0ins.cc:1337
#13 0x0000000001f6e66d in row_ins_check_foreign_constraint (check_ref=<optimized out>, 
    foreign=<optimized out>, table=<optimized out>, entry=<optimized out>, thr=<optimized out>)
    at /mariadb/10.5m/storage/innobase/row/row0ins.cc:1744
#14 0x00000000020c4b03 in row_upd_check_references_constraints (node=0x620000013c38, 
    pcur=<optimized out>, table=<optimized out>, index=0x61700005c9a0, offsets=<optimized out>, 
    thr=0x6240000fc1a0, mtr=0x7f3809978350) at /mariadb/10.5m/storage/innobase/row/row0upd.cc:295
#15 0x00000000020b5665 in row_upd_del_mark_clust_rec (node=0x620000013bb8, index=0x61700005c9a0, 
    offsets=0x7f38099788a0, thr=0x6240000fc1a0, referenced=1, mtr=0x7f3809978350, 
    foreign=<optimized out>) at /mariadb/10.5m/storage/innobase/row/row0upd.cc:2691
#16 row_upd_clust_step (node=0x620000013bb8, thr=0x6240000fc1a0)
    at /mariadb/10.5m/storage/innobase/row/row0upd.cc:2860
#17 row_upd (node=<optimized out>, thr=0x6240000fc1a0)
    at /mariadb/10.5m/storage/innobase/row/row0upd.cc:2992
#18 0x00000000020b334a in row_upd_step (thr=0x6240000fc1a0)
    at /mariadb/10.5m/storage/innobase/row/row0upd.cc:3136
#19 0x0000000001fe05c8 in row_update_for_mysql (prebuilt=0x620000013120)
    at /mariadb/10.5m/storage/innobase/row/row0mysql.cc:1847
#20 0x0000000001c37c05 in ha_innobase::delete_row (this=0x61d000268eb8, record=0x6190000d5cc8 "\001")
    at /mariadb/10.5m/storage/innobase/handler/ha_innodb.cc:8471
#21 0x000000000121bd74 in handler::ha_delete_row (this=0x61d000268eb8, buf=<optimized out>)

Comment by Marko Mäkelä [ 2020-10-27 ]

I can repeat this on the latest 10.2 as well. For debugging, I suggest using an ASAN build with rr record and setting a watchpoint on the ASAN poison bytes.

ASAN will tell that it is a heap-use-after-free and that the offending mem_heap_empty() was invoked earlier during the processing of the DELETE statement.

Comment by Nikita Malyavin [ 2020-12-16 ]

An adopted test

--source include/have_innodb.inc
 
CREATE TABLE emails (
  id int,
  PRIMARY KEY (id)
) ENGINE=InnoDB;
 
CREATE TABLE email_stats (
  id int,
  email_id int,
  date_sent char(4),
  generated_email_id int as (email_id),
  PRIMARY KEY (id),
  KEY mautic_generated_sent_date_email_id (generated_email_id),
  FOREIGN KEY (email_id) REFERENCES emails (id) ON DELETE SET NULL
) ENGINE=InnoDB;
 
 
CREATE TABLE emails_metadata (
  email_id int,
  PRIMARY KEY (email_id),
  CONSTRAINT FK FOREIGN KEY (email_id) REFERENCES emails (id) ON DELETE CASCADE
) ENGINE=InnoDB;
 
 
INSERT INTO emails VALUES (1);
INSERT INTO email_stats (id, email_id,  date_sent) VALUES (1,1,'Jan');
INSERT INTO emails_metadata VALUES (1);
 
COMMIT;
 
DELETE FROM emails;
 
drop table email_stats;
drop table emails_metadata;
drop table emails;

With ASAN gives an assertion:

----------SERVER LOG START-----------
2020-12-16 21:41:06 0 [Note] /home/nik/mariadb/bld/sql/mysqld (mysqld 10.3.28-MariaDB-debug-log) starting as process 30222 ...
2020-12-16 21:41:06 0 [Warning] Could not increase number of max_open_files to more than 1024 (request: 32194)
2020-12-16 21:41:06 0 [Warning] Changed limits: max_open_files: 1024  max_connections: 151 (was 151)  table_cache: 421 (was 2000)
2020-12-16 21:41:06 0 [Note] Plugin 'partition' is disabled.
2020-12-16 21:41:06 0 [Note] InnoDB: Using Linux native AIO
2020-12-16 21:41:06 0 [Note] InnoDB: !!!!!!!! UNIV_DEBUG switched on !!!!!!!!!
2020-12-16 21:41:06 0 [Note] InnoDB: Mutexes and rw_locks use GCC atomic builtins
2020-12-16 21:41:06 0 [Note] InnoDB: Uses event mutexes
2020-12-16 21:41:06 0 [Note] InnoDB: Compressed tables use zlib 1.2.11
2020-12-16 21:41:06 0 [Note] InnoDB: Number of pools: 1
2020-12-16 21:41:06 0 [Note] InnoDB: Using SSE2 crc32 instructions
2020-12-16 21:41:06 0 [Note] InnoDB: Initializing buffer pool, total size = 8M, instances = 1, chunk size = 8M
2020-12-16 21:41:06 0 [Note] InnoDB: Completed initialization of buffer pool
2020-12-16 21:41:06 0 [Note] InnoDB: If the mysqld execution user is authorized, page cleaner thread priority can be changed. See the man page of setpriority().
2020-12-16 21:41:06 0 [Note] InnoDB: 128 out of 128 rollback segments are active.
2020-12-16 21:41:06 0 [Note] InnoDB: Creating shared tablespace for temporary tables
2020-12-16 21:41:06 0 [Note] InnoDB: Setting file './ibtmp1' size to 12 MB. Physically writing the file full; Please wait ...
2020-12-16 21:41:06 0 [Note] InnoDB: File './ibtmp1' size is now 12 MB.
2020-12-16 21:41:06 0 [Note] InnoDB: Waiting for purge to start
2020-12-16 21:41:07 0 [Note] InnoDB: 10.3.28 started; log sequence number 1636536; transaction id 33
2020-12-16 21:41:07 0 [Note] InnoDB: Loading buffer pool(s) from /dev/shm/var_auto_Q4M8/mysqld.1/data/ib_buffer_pool
2020-12-16 21:41:07 0 [Note] Plugin 'SEQUENCE' is disabled.
2020-12-16 21:41:07 0 [Note] Plugin 'INNODB_SYS_DATAFILES' is disabled.
2020-12-16 21:41:07 0 [Note] InnoDB: Buffer pool(s) load completed at 201216 21:41:07
2020-12-16 21:41:07 0 [Note] Plugin 'INNODB_SYS_TABLESTATS' is disabled.
2020-12-16 21:41:07 0 [Note] Plugin 'INNODB_MUTEXES' is disabled.
2020-12-16 21:41:07 0 [Note] Plugin 'INNODB_CMP' is disabled.
2020-12-16 21:41:07 0 [Note] Plugin 'INNODB_FT_DELETED' is disabled.
2020-12-16 21:41:07 0 [Note] Plugin 'INNODB_CMP_RESET' is disabled.
2020-12-16 21:41:07 0 [Note] Plugin 'INNODB_TABLESPACES_ENCRYPTION' is disabled.
2020-12-16 21:41:07 0 [Note] Plugin 'INNODB_CMPMEM_RESET' is disabled.
2020-12-16 21:41:07 0 [Note] Plugin 'FEEDBACK' is disabled.
2020-12-16 21:41:07 0 [Note] Plugin 'INNODB_FT_INDEX_TABLE' is disabled.
2020-12-16 21:41:07 0 [Note] Plugin 'INNODB_CMP_PER_INDEX_RESET' is disabled.
2020-12-16 21:41:07 0 [Note] Plugin 'user_variables' is disabled.
2020-12-16 21:41:07 0 [Note] Plugin 'INNODB_FT_INDEX_CACHE' is disabled.
2020-12-16 21:41:07 0 [Note] Plugin 'INNODB_FT_BEING_DELETED' is disabled.
2020-12-16 21:41:07 0 [Note] Plugin 'INNODB_FT_DEFAULT_STOPWORD' is disabled.
2020-12-16 21:41:07 0 [Note] Plugin 'INNODB_FT_CONFIG' is disabled.
2020-12-16 21:41:07 0 [Note] Plugin 'INNODB_SYS_TABLESPACES' is disabled.
2020-12-16 21:41:07 0 [Note] Plugin 'INNODB_TABLESPACES_SCRUBBING' is disabled.
2020-12-16 21:41:07 0 [Note] Plugin 'INNODB_SYS_SEMAPHORE_WAITS' is disabled.
2020-12-16 21:41:07 0 [Note] Plugin 'unix_socket' is disabled.
2020-12-16 21:41:07 0 [Warning] /home/nik/mariadb/bld/sql/mysqld: unknown option '--loose-pam-debug'
2020-12-16 21:41:07 0 [Note] Server socket created on IP: '127.0.0.1'.
2020-12-16 21:41:07 0 [Note] Reading of all Master_info entries succeeded
2020-12-16 21:41:07 0 [Note] Added new Master_info '' to hash table
2020-12-16 21:41:07 0 [Note] /home/nik/mariadb/bld/sql/mysqld: ready for connections.
Version: '10.3.28-MariaDB-debug-log'  socket: '/home/nik/mariadb/bld/mysql-test/var/tmp/mysqld.1.sock'  port: 16000  Source distribution
=================================================================
==30222==ERROR: AddressSanitizer: heap-use-after-free on address 0x616000060af0 at pc 0x555f3225e044 bp 0x7f1edfa20b80 sp 0x7f1edfa20b78
READ of size 8 at 0x616000060af0 thread T24
    #0 0x555f3225e043 in dtuple_get_nth_v_field(dtuple_t*, unsigned long) /home/nik/mariadb/bld/../storage/innobase/include/data0data.h:611:2
    #1 0x555f3276f187 in row_upd_store_v_row(upd_node_t*, upd_t const*, THD*, TABLE*) /home/nik/mariadb/bld/../storage/innobase/row/row0upd.cc:2162:10
    #2 0x555f327699c3 in row_upd_store_row(upd_node_t*, THD*, TABLE*) /home/nik/mariadb/bld/../storage/innobase/row/row0upd.cc:2243:13
    #3 0x555f32764c5c in row_upd_clust_step(upd_node_t*, que_thr_t*) /home/nik/mariadb/bld/../storage/innobase/row/row0upd.cc:3203:6
    #4 0x555f3275d9b4 in row_upd(upd_node_t*, que_thr_t*) /home/nik/mariadb/bld/../storage/innobase/row/row0upd.cc:3302:9
    #5 0x555f3275cbcc in row_upd_step(que_thr_t*) /home/nik/mariadb/bld/../storage/innobase/row/row0upd.cc:3446:8
    #6 0x555f3264a32f in row_update_cascade_for_mysql(que_thr_t*, upd_node_t*, dict_table_t*) /home/nik/mariadb/bld/../storage/innobase/row/row0mysql.cc:2222:4
    #7 0x555f325caf5e in row_ins_foreign_check_on_constraint(que_thr_t*, dict_foreign_t*, btr_pcur_t*, dtuple_t*, mtr_t*) /home/nik/mariadb/bld/../storage/innobase/row/row0ins.cc:1339:8
    #8 0x555f325c5666 in row_ins_check_foreign_constraint(unsigned long, dict_foreign_t*, dict_table_t*, dtuple_t*, que_thr_t*) /home/nik/mariadb/bld/../storage/innobase/row/row0ins.cc:1762:12
    #9 0x555f3276cfc0 in row_upd_check_references_constraints(upd_node_t*, btr_pcur_t*, dict_table_t*, dict_index_t*, unsigned short*, que_thr_t*, mtr_t*) /home/nik/mariadb/bld/../storage/innobase/row/row0upd.cc:295:10
    #10 0x555f3276708b in row_upd_del_mark_clust_rec(upd_node_t*, dict_index_t*, unsigned short*, que_thr_t*, unsigned long, bool, mtr_t*) /home/nik/mariadb/bld/../storage/innobase/row/row0upd.cc:3000:9
    #11 0x555f327647e1 in row_upd_clust_step(upd_node_t*, que_thr_t*) /home/nik/mariadb/bld/../storage/innobase/row/row0upd.cc:3170:9
    #12 0x555f3275d9b4 in row_upd(upd_node_t*, que_thr_t*) /home/nik/mariadb/bld/../storage/innobase/row/row0upd.cc:3302:9
    #13 0x555f3275cbcc in row_upd_step(que_thr_t*) /home/nik/mariadb/bld/../storage/innobase/row/row0upd.cc:3446:8
    #14 0x555f326464ec in row_update_for_mysql(row_prebuilt_t*) /home/nik/mariadb/bld/../storage/innobase/row/row0mysql.cc:1847:3
    #15 0x555f321dd7ed in ha_innobase::delete_row(unsigned char const*) /home/nik/mariadb/bld/../storage/innobase/handler/ha_innodb.cc:8948:10
    #16 0x555f31a7ec6a in handler::ha_delete_row(unsigned char const*) /home/nik/mariadb/bld/../sql/handler.cc:6554:3
    #17 0x555f32040274 in TABLE::delete_row() /home/nik/mariadb/bld/../sql/sql_delete.cc:245:18
    #18 0x555f32033a04 in mysql_delete(THD*, TABLE_LIST*, Item*, SQL_I_List<st_order>*, unsigned long long, unsigned long long, select_result*) /home/nik/mariadb/bld/../sql/sql_delete.cc:720:21
    #19 0x555f30fdd0c3 in mysql_execute_command(THD*) /home/nik/mariadb/bld/../sql/sql_parse.cc:4684:11
    #20 0x555f30fc38ec in mysql_parse(THD*, char*, unsigned int, Parser_state*, bool, bool) /home/nik/mariadb/bld/../sql/sql_parse.cc:7837:18
    #21 0x555f30fb3951 in dispatch_command(enum_server_command, THD*, char*, unsigned int, bool, bool) /home/nik/mariadb/bld/../sql/sql_parse.cc:1852:7
    #22 0x555f30fbd5bc in do_command(THD*) /home/nik/mariadb/bld/../sql/sql_parse.cc:1398:17
    #23 0x555f3150b882 in do_handle_one_connection(CONNECT*) /home/nik/mariadb/bld/../sql/sql_connect.cc:1403:11
    #24 0x555f3150af33 in handle_one_connection /home/nik/mariadb/bld/../sql/sql_connect.cc:1308:3
    #25 0x555f3338ea61 in pfs_spawn_thread /home/nik/mariadb/bld/../storage/perfschema/pfs.cc:1869:3
    #26 0x7f1ef53ce3e8 in start_thread (/usr/lib/libpthread.so.0+0x93e8)
    #27 0x7f1ef4aa0292 in clone (/usr/lib/libc.so.6+0x100292)
 
0x616000060af0 is located 368 bytes inside of 640-byte region [0x616000060980,0x616000060c00)
freed by thread T24 here:
    #0 0x555f30b89a29 in free (/home/nik/mariadb/bld/sql/mysqld+0x1030a29)
    #1 0x555f32468f88 in mem_heap_block_free(mem_block_info_t*, mem_block_info_t*) /home/nik/mariadb/bld/../storage/innobase/mem/mem0mem.cc:416:3
    #2 0x555f327745f7 in mem_heap_free_heap_top(mem_block_info_t*, unsigned char*) /home/nik/mariadb/bld/../storage/innobase/include/mem0mem.ic:259:3
    #3 0x555f327658ba in mem_heap_empty(mem_block_info_t*) /home/nik/mariadb/bld/../storage/innobase/include/mem0mem.ic:290:2
    #4 0x555f32769550 in row_upd_store_row(upd_node_t*, THD*, TABLE*) /home/nik/mariadb/bld/../storage/innobase/row/row0upd.cc:2216:3
    #5 0x555f32764c5c in row_upd_clust_step(upd_node_t*, que_thr_t*) /home/nik/mariadb/bld/../storage/innobase/row/row0upd.cc:3203:6
    #6 0x555f3275d9b4 in row_upd(upd_node_t*, que_thr_t*) /home/nik/mariadb/bld/../storage/innobase/row/row0upd.cc:3302:9
    #7 0x555f3275cbcc in row_upd_step(que_thr_t*) /home/nik/mariadb/bld/../storage/innobase/row/row0upd.cc:3446:8
    #8 0x555f3264a32f in row_update_cascade_for_mysql(que_thr_t*, upd_node_t*, dict_table_t*) /home/nik/mariadb/bld/../storage/innobase/row/row0mysql.cc:2222:4
    #9 0x555f325caf5e in row_ins_foreign_check_on_constraint(que_thr_t*, dict_foreign_t*, btr_pcur_t*, dtuple_t*, mtr_t*) /home/nik/mariadb/bld/../storage/innobase/row/row0ins.cc:1339:8
    #10 0x555f325c5666 in row_ins_check_foreign_constraint(unsigned long, dict_foreign_t*, dict_table_t*, dtuple_t*, que_thr_t*) /home/nik/mariadb/bld/../storage/innobase/row/row0ins.cc:1762:12
    #11 0x555f3276cfc0 in row_upd_check_references_constraints(upd_node_t*, btr_pcur_t*, dict_table_t*, dict_index_t*, unsigned short*, que_thr_t*, mtr_t*) /home/nik/mariadb/bld/../storage/innobase/row/row0upd.cc:295:10
    #12 0x555f3276708b in row_upd_del_mark_clust_rec(upd_node_t*, dict_index_t*, unsigned short*, que_thr_t*, unsigned long, bool, mtr_t*) /home/nik/mariadb/bld/../storage/innobase/row/row0upd.cc:3000:9
    #13 0x555f327647e1 in row_upd_clust_step(upd_node_t*, que_thr_t*) /home/nik/mariadb/bld/../storage/innobase/row/row0upd.cc:3170:9
    #14 0x555f3275d9b4 in row_upd(upd_node_t*, que_thr_t*) /home/nik/mariadb/bld/../storage/innobase/row/row0upd.cc:3302:9
    #15 0x555f3275cbcc in row_upd_step(que_thr_t*) /home/nik/mariadb/bld/../storage/innobase/row/row0upd.cc:3446:8
    #16 0x555f326464ec in row_update_for_mysql(row_prebuilt_t*) /home/nik/mariadb/bld/../storage/innobase/row/row0mysql.cc:1847:3
    #17 0x555f321dd7ed in ha_innobase::delete_row(unsigned char const*) /home/nik/mariadb/bld/../storage/innobase/handler/ha_innodb.cc:8948:10
    #18 0x555f31a7ec6a in handler::ha_delete_row(unsigned char const*) /home/nik/mariadb/bld/../sql/handler.cc:6554:3
    #19 0x555f32040274 in TABLE::delete_row() /home/nik/mariadb/bld/../sql/sql_delete.cc:245:18
    #20 0x555f32033a04 in mysql_delete(THD*, TABLE_LIST*, Item*, SQL_I_List<st_order>*, unsigned long long, unsigned long long, select_result*) /home/nik/mariadb/bld/../sql/sql_delete.cc:720:21
    #21 0x555f30fdd0c3 in mysql_execute_command(THD*) /home/nik/mariadb/bld/../sql/sql_parse.cc:4684:11
    #22 0x555f30fc38ec in mysql_parse(THD*, char*, unsigned int, Parser_state*, bool, bool) /home/nik/mariadb/bld/../sql/sql_parse.cc:7837:18
    #23 0x555f30fb3951 in dispatch_command(enum_server_command, THD*, char*, unsigned int, bool, bool) /home/nik/mariadb/bld/../sql/sql_parse.cc:1852:7
    #24 0x555f30fbd5bc in do_command(THD*) /home/nik/mariadb/bld/../sql/sql_parse.cc:1398:17
    #25 0x555f3150b882 in do_handle_one_connection(CONNECT*) /home/nik/mariadb/bld/../sql/sql_connect.cc:1403:11
    #26 0x555f3150af33 in handle_one_connection /home/nik/mariadb/bld/../sql/sql_connect.cc:1308:3
    #27 0x555f3338ea61 in pfs_spawn_thread /home/nik/mariadb/bld/../storage/perfschema/pfs.cc:1869:3
    #28 0x7f1ef53ce3e8 in start_thread (/usr/lib/libpthread.so.0+0x93e8)
 
previously allocated by thread T24 here:
    #0 0x555f30b89d59 in malloc (/home/nik/mariadb/bld/sql/mysqld+0x1030d59)
    #1 0x555f32467910 in mem_heap_create_block_func(mem_block_info_t*, unsigned long, char const*, unsigned int, unsigned long) /home/nik/mariadb/bld/../storage/innobase/mem/mem0mem.cc:277:37
    #2 0x555f32468b54 in mem_heap_add_block(mem_block_info_t*, unsigned long) /home/nik/mariadb/bld/../storage/innobase/mem/mem0mem.cc:378:14
    #3 0x555f326cdd38 in mem_heap_alloc(mem_block_info_t*, unsigned long) /home/nik/mariadb/bld/../storage/innobase/include/mem0mem.ic:191:11
    #4 0x555f326c9a94 in dtuple_create_with_vcol(mem_block_info_t*, unsigned long, unsigned long) /home/nik/mariadb/bld/../storage/innobase/include/data0data.ic:397:8
    #5 0x555f326cc5e8 in row_build_low(unsigned long, dict_index_t const*, unsigned char const*, unsigned short const*, dict_table_t const*, dtuple_t const*, dict_add_v_col_t const*, unsigned long const*, row_ext_t**, mem_block_info_t*) /home/nik/mariadb/bld/../storage/innobase/row/row0row.cc:490:9
    #6 0x555f326cb859 in row_build(unsigned long, dict_index_t const*, unsigned char const*, unsigned short const*, dict_table_t const*, dtuple_t const*, unsigned long const*, row_ext_t**, mem_block_info_t*) /home/nik/mariadb/bld/../storage/innobase/row/row0row.cc:628:9
    #7 0x555f327697ca in row_upd_store_row(upd_node_t*, THD*, TABLE*) /home/nik/mariadb/bld/../storage/innobase/row/row0upd.cc:2239:14
    #8 0x555f32766eb2 in row_upd_del_mark_clust_rec(upd_node_t*, dict_index_t*, unsigned short*, que_thr_t*, unsigned long, bool, mtr_t*) /home/nik/mariadb/bld/../storage/innobase/row/row0upd.cc:2980:7
    #9 0x555f327647e1 in row_upd_clust_step(upd_node_t*, que_thr_t*) /home/nik/mariadb/bld/../storage/innobase/row/row0upd.cc:3170:9
    #10 0x555f3275d9b4 in row_upd(upd_node_t*, que_thr_t*) /home/nik/mariadb/bld/../storage/innobase/row/row0upd.cc:3302:9
    #11 0x555f3275cbcc in row_upd_step(que_thr_t*) /home/nik/mariadb/bld/../storage/innobase/row/row0upd.cc:3446:8
    #12 0x555f3264a32f in row_update_cascade_for_mysql(que_thr_t*, upd_node_t*, dict_table_t*) /home/nik/mariadb/bld/../storage/innobase/row/row0mysql.cc:2222:4
    #13 0x555f325caf5e in row_ins_foreign_check_on_constraint(que_thr_t*, dict_foreign_t*, btr_pcur_t*, dtuple_t*, mtr_t*) /home/nik/mariadb/bld/../storage/innobase/row/row0ins.cc:1339:8
    #14 0x555f325c5666 in row_ins_check_foreign_constraint(unsigned long, dict_foreign_t*, dict_table_t*, dtuple_t*, que_thr_t*) /home/nik/mariadb/bld/../storage/innobase/row/row0ins.cc:1762:12
    #15 0x555f3276cfc0 in row_upd_check_references_constraints(upd_node_t*, btr_pcur_t*, dict_table_t*, dict_index_t*, unsigned short*, que_thr_t*, mtr_t*) /home/nik/mariadb/bld/../storage/innobase/row/row0upd.cc:295:10
    #16 0x555f3276708b in row_upd_del_mark_clust_rec(upd_node_t*, dict_index_t*, unsigned short*, que_thr_t*, unsigned long, bool, mtr_t*) /home/nik/mariadb/bld/../storage/innobase/row/row0upd.cc:3000:9
    #17 0x555f327647e1 in row_upd_clust_step(upd_node_t*, que_thr_t*) /home/nik/mariadb/bld/../storage/innobase/row/row0upd.cc:3170:9
    #18 0x555f3275d9b4 in row_upd(upd_node_t*, que_thr_t*) /home/nik/mariadb/bld/../storage/innobase/row/row0upd.cc:3302:9
    #19 0x555f3275cbcc in row_upd_step(que_thr_t*) /home/nik/mariadb/bld/../storage/innobase/row/row0upd.cc:3446:8
    #20 0x555f326464ec in row_update_for_mysql(row_prebuilt_t*) /home/nik/mariadb/bld/../storage/innobase/row/row0mysql.cc:1847:3
    #21 0x555f321dd7ed in ha_innobase::delete_row(unsigned char const*) /home/nik/mariadb/bld/../storage/innobase/handler/ha_innodb.cc:8948:10
    #22 0x555f31a7ec6a in handler::ha_delete_row(unsigned char const*) /home/nik/mariadb/bld/../sql/handler.cc:6554:3
    #23 0x555f32040274 in TABLE::delete_row() /home/nik/mariadb/bld/../sql/sql_delete.cc:245:18
    #24 0x555f32033a04 in mysql_delete(THD*, TABLE_LIST*, Item*, SQL_I_List<st_order>*, unsigned long long, unsigned long long, select_result*) /home/nik/mariadb/bld/../sql/sql_delete.cc:720:21
    #25 0x555f30fdd0c3 in mysql_execute_command(THD*) /home/nik/mariadb/bld/../sql/sql_parse.cc:4684:11
    #26 0x555f30fc38ec in mysql_parse(THD*, char*, unsigned int, Parser_state*, bool, bool) /home/nik/mariadb/bld/../sql/sql_parse.cc:7837:18
    #27 0x555f30fb3951 in dispatch_command(enum_server_command, THD*, char*, unsigned int, bool, bool) /home/nik/mariadb/bld/../sql/sql_parse.cc:1852:7
    #28 0x555f30fbd5bc in do_command(THD*) /home/nik/mariadb/bld/../sql/sql_parse.cc:1398:17
    #29 0x555f3150b882 in do_handle_one_connection(CONNECT*) /home/nik/mariadb/bld/../sql/sql_connect.cc:1403:11
 
Thread T24 created by T0 here:
    #0 0x555f30aff714 in pthread_create (/home/nik/mariadb/bld/sql/mysqld+0xfa6714)
    #1 0x555f33394ed9 in spawn_thread_v1(unsigned int, unsigned long*, pthread_attr_t const*, void* (*)(void*), void*) /home/nik/mariadb/bld/../storage/perfschema/pfs.cc:1919:15
    #2 0x555f30bcba1a in inline_mysql_thread_create(unsigned int, unsigned long*, pthread_attr_t const*, void* (*)(void*), void*) /home/nik/mariadb/bld/../include/mysql/psi/mysql_thread.h:1275:11
    #3 0x555f30bdd552 in create_thread_to_handle_connection(CONNECT*) /home/nik/mariadb/bld/../sql/mysqld.cc:6658:15
    #4 0x555f30bdedea in create_new_thread(CONNECT*) /home/nik/mariadb/bld/../sql/mysqld.cc:6728:3
    #5 0x555f30bdca75 in handle_connections_sockets() /home/nik/mariadb/bld/../sql/mysqld.cc:6986:9
    #6 0x555f30bcf3ce in mysqld_main(int, char**) /home/nik/mariadb/bld/../sql/mysqld.cc:6280:3
    #7 0x555f30bc2921 in main /home/nik/mariadb/bld/../sql/main.cc:25:10
    #8 0x7f1ef49c8151 in __libc_start_main (/usr/lib/libc.so.6+0x28151)
 
SUMMARY: AddressSanitizer: heap-use-after-free /home/nik/mariadb/bld/../storage/innobase/include/data0data.h:611:2 in dtuple_get_nth_v_field(dtuple_t*, unsigned long)
Shadow bytes around the buggy address:
  0x0c2c80004100: 00 00 00 00 00 00 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7
  0x0c2c80004110: f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7
  0x0c2c80004120: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c2c80004130: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0c2c80004140: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
=>0x0c2c80004150: fd fd fd fd fd fd fd fd fd fd fd fd fd fd[fd]fd
  0x0c2c80004160: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0c2c80004170: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0c2c80004180: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c2c80004190: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c2c800041a0: f7 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07 
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
  Shadow gap:              cc
==30222==ABORTING
----------SERVER LOG END-------------

Comment by Nikita Malyavin [ 2020-12-17 ]

Turns out to be a one-liner �

marko Please review commit 252f8ec4

Comment by Marko Mäkelä [ 2020-12-17 ]

Thank you. My suggested wording for the commit message would be as follows:

MDEV-24041 Generated column DELETE with FOREIGN KEY crash InnoDB
 
row_upd_clust_step() invokes row_upd_del_mark_clust_rec(), which would
allocate some memory in row_ins_foreign_fill_virtual(). Then,
row_upd_store_row() would access the allocated memory, but only after
potentially freeing that memory by invoking mem_heap_empty().
This would lead to ASAN heap-use-after-free diagnostics.
 
row_ins_foreign_fill_virtual(): Use a memory heap with a longer lifetime.

Comment by Marko Mäkelä [ 2021-07-23 ]

MDEV-26228 is a follow-up to this, for UPDATE and ON UPDATE CASCADE.

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