[MDEV-17005] ASAN heap-use-after-free in innobase_get_computed_value Created: 2018-08-16 Updated: 2019-10-11 Resolved: 2019-07-22 |
|
| Status: | Closed |
| Project: | MariaDB Server |
| Component/s: | Data Definition - Alter Table, Locking, Storage Engine - InnoDB, Virtual Columns |
| Affects Version/s: | 10.2, 10.3, 10.4 |
| Fix Version/s: | 10.2.26, 10.3.17, 10.4.7 |
| Type: | Bug | Priority: | Critical |
| Reporter: | Elena Stepanova | Assignee: | Nikita Malyavin |
| Resolution: | Fixed | Votes: | 0 |
| Labels: | affects-tests | ||
| Attachments: |
|
||||||||||||||||||||||||||||
| Issue Links: |
|
||||||||||||||||||||||||||||
| Sub-Tasks: |
|
||||||||||||||||||||||||||||
| Description |
|
To reproduce:
Notes:
|
| Comments |
| Comment by Elena Stepanova [ 2018-10-07 ] | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Possibly related:
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Elena Stepanova [ 2018-10-31 ] | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
New occurrence of the failure from the previous comment on 10.2: http://buildbot.askmonty.org/buildbot/builders/qa-win-rel/builds/5462/steps/result_summary/logs/stdio | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Marko Mäkelä [ 2018-11-01 ] | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
I can repeat easily:
It seems to me that LOAD DATA INFILE is accessing a freed TABLE_SHARE object. Could we be missing a metadata lock (MDL) that wrongly allowed the LOAD DATA INFILE to execute concurrently with the ALTER TABLE that took place in Thread 33? If the SQL layer is always providing the values for indexed virtual columns before invoking handler::ha_delete_row(), then InnoDB should use those values and not evaluate any virtual columns during DML processing (well, except if FOREIGN KEY constraints are involved). | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Marko Mäkelä [ 2018-11-01 ] | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
svoj, could you check if there is a problem with the MDL that could cause a race condition between LOAD DATA and ALTER TABLE? | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Matthias Leich [ 2018-11-02 ] | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Elena Stepanova [ 2019-01-27 ] | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Test cases attached by Matthias fail quite readily on 10.3 ASAN – mdev-17005.test fails for me with the ASAN failure described here, mdev-17005_longer.test – with Here is a shorter MTR test case. It's also non-deterministic, run with --repeat=N. It usually fails for me within first 1-2 attempts, on all of 10.2-10.4.
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Sergey Vojtovich [ 2019-04-03 ] | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
marko, according to the last test case provided by Elena, it is not "the MDL that could cause a race condition between LOAD DATA and ALTER TABLE" (because DELETE and INSERT and not LOAD DATA and ALTER TABLE are being executed concurrently, which are compatible from the MDL view). | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Nikita Malyavin [ 2019-07-15 ] | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
marko, I confirm that it is the race between DELETE and INSERT (or other any two operations accessing to the table). What actually happens: Please, review the fix: https://github.com/MariaDB/server/commits/bb-10.2-MDEV-17005 | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Marko Mäkelä [ 2019-07-18 ] | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Great work! I only have a minor suggestion that should reduce the probability of memory fragmentation: Make dict_vcol_templ_t::default_rec a variable-length array that is at the end of the structure. In this way, the memory could be allocated upfront. But, now I realize that we do not know s_templ->rec_len = table->s->reclength before the table has been looked up, and thus we cannot allocate memory for default_rec when creating s_templ. Your fix is OK to push, but I feel that this area of code needs to be redesigned and rewritten at some point. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Nikita Malyavin [ 2019-07-22 ] | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
marko I think that we shouldn't access TABLE_SHARE on each open. We can just store all the vcol info similar to usual columns in system innodb table, with additional flag, and fill out dict_vcol_templ_t once the dict_table_t has been created. For now we can't do that because of architecture: real dict_table_t creation is deep inside innodb, and it shouldn't know anything about TABLE_SHARE there. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Marko Mäkelä [ 2019-07-22 ] | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
I would like to get rid of the InnoDB system tables (MDEV-11655), not extend the use of them. To my knowledge, InnoDB never stored the expressions of virtual columns, which are needed for evaluation. Those are only available via TABLE_SHARE (and .frm files). I think that we should look at changing the undo logging. If the virtual column values are written in the undo log records in an appropriate way (MDEV-11657, |