• Nikita Malyavin's avatar
    MDEV-17005 ASAN heap-use-after-free in innobase_get_computed_value · 12614af1
    Nikita Malyavin authored
    This is the race between DELETE and INSERT (or other any two operations accessing to the table).
    What should happen in good case:
    1. ALTER TABLE is issued. vc_templ->default_rec is initialized with temporary share's default_fields
    2. temporary share is freed, but datadict is still there, with garbage in vc_templ->default_rec
    3. DELETE is issued. It is first after ALTER TABLE finished.
    4. ha_innobase::open() is called, ib_table->get_ref_count() should be one
    5. we reinitialize vc_templ, so no garbage anymore
    
    What actually happens:
    3. DELETE is issued.
    4. ha_innobase::open() is called and ib_table->get_ref_count() is 1
    5. INSERT (or SELECT etc.) is issued in parallel
    6. ha_innobase::open() is called and ib_table->get_ref_count() is 1
    7. we check ib_table->get_ref_count()  and it is 2 in both threads when we want reinitialize vc_templ
    8. garbage is there
    
    Fix:
    * Do not store pointers to SHARE memory in table dict, copy it instead.
    * But then we don't need to refresh it each time when refcount=1.
    12614af1
dict0dict.ic 42.3 KB