memtx: fix use-after-free on background index build
When building an index in background, we create on_rollback triggers for tuples inserted concurrently. The problem here is on_rollback trigger has independent from `index` and `memtx_ddl_state` lifetime - it can be called after the index was build (and `memtx_ddl_state` is destroyed) and even after the index was altered. So, in order to avoid use-after-free in on_rollback trigger, let's drop all on_rollback triggers when the DDL is over. It's OK because all owners of triggers are already prepared, hence, in WAL or replication queue (since we build indexes in background only without MVCC so the transactions cannot yield), so if they are rolled back, the same will happen to the DDL. In order to delete on_rollback triggers, we should collect them into a list in `memtx_ddl_state`. On the other hand, when the DML statement is over (committed or rolled back), we should delete its trigger from the list to prevent use-after-free. That's why the commit adds the on_commit trigger to background build process. Closes #10620 NO_DOC=bugfix (cherry picked from commit d8d82dba4c884c3a7ad825bd3452d35627c7dbf4)
Showing
- changelogs/unreleased/gh-10620-crash-on-rollback-after-background-index-build.md 4 additions, 0 deletions...h-10620-crash-on-rollback-after-background-index-build.md
- src/box/memtx_space.c 67 additions, 40 deletionssrc/box/memtx_space.c
- src/lib/core/errinj.h 0 additions, 1 deletionsrc/lib/core/errinj.h
- test/box/errinj.result 0 additions, 90 deletionstest/box/errinj.result
- test/box/errinj.test.lua 0 additions, 58 deletionstest/box/errinj.test.lua
- test/engine-luatest/gh_10620_crash_on_rollback_after_background_index_build_test.lua 77 additions, 0 deletions...0_crash_on_rollback_after_background_index_build_test.lua
Loading
Please register or sign in to comment