[email protected] wrote: > Full_Name: Markus Junginger > Version: mdb.master > OS: Ubuntu > URL: ftp://ftp.openldap.org/incoming/ > Submission from: (NULL) (77.190.230.93) > > > Read cursors may outlive a transaction to be renewed with another. Thus, > cursors > should be correctly closed even after their last transaction was aborted. But > they access the (already freed) transaction during closing when MDB_VL32 is > used > (mdb.master branch). > > ASan captures this like this: > ==19722==ERROR: AddressSanitizer: heap-use-after-free on address > 0x61100001b140 > at pc 0x000000ea2387 bp 0x7ffd36e3cd20 sp 0x7ffd36e3cd18 > READ of size 8 at 0x61100001b140 thread T0 > #0 0xea2386 in mdb_cursor_unref mdb.c:2082:18 > #1 0xec577b in mdb_cursor_close mdb.c:8538:3 > > 0x61100001b140 is located 128 bytes inside of 250-byte region > [0x61100001b0c0,0x61100001b1ba) > freed by thread T0 here: > #0 0x74f840 in __interceptor_cfree.localalias.0 (...) > #1 0xe8ea98 in mdb_txn_end mdb.c:3380:3 > #2 0xe8ecc5 in mdb_txn_abort mdb.c:3405:2 > > > Possible fix for line mdb.c:2082 (applying what I found in mdb_cursor_close): > - if (mc->mc_txn->mt_rpages[0].mid) { > + if ((mc->mc_flags & C_UNTRACK) && mc->mc_txn->mt_rpages[0].mid) { > > > Code to reproduce using MDB_VL32: > err = mdb_txn_begin(env, nullptr, MDB_RDONLY, &tx); > err = mdb_cursor_open(tx, dbi, &cursor); > // We must have data so get will set C_INITIALIZED > err = mdb_cursor_get(cursor, &key, &value, MDB_SET_KEY); > mdb_txn_abort(tx); > mdb_cursor_close(cursor); // <- still uses tx
Thanks for the report. Unfortunately your suggested fix means the rpage test will always be skipped on read-only cursors, which will break the rpage tracking if the txn is still alive. -- -- Howard Chu CTO, Symas Corp. http://www.symas.com Director, Highland Sun http://highlandsun.com/hyc/ Chief Architect, OpenLDAP http://www.openldap.org/project/
