On Wed, Oct 16, 2019 at 01:59:51AM +0100, Howard Chu wrote:
christopher@gmerlin.de wrote:
Full_Name: Christopher Zimmermann Version: lmdb 0.9.24 OS: OpenBSD URL: ftp://ftp.openldap.org/incoming/ Submission from: (NULL) (85.212.180.240)
Hi,
I can reliably hit a Bus error on OpenBSD. This is triggered by OpenBSDs malloc/free junking [1] and a use-after-free bug in lmdb.
Steps to reproduce:
- begin a read/write transaction (getting env->me_txn0)
- fill the environment -> returns MDB_MAP_FULL -> sets txn->mt_flags |= MDB_TXN_ERROR; (This is also env->me_txn0 !) -> calls mdb_txn_abort
...
- abort the transaction (again) with mdb_abort()
This is a bug in your code, you can't call txn_abort twice. This is already documented. Closing this ITS.
Hi,
thanks for having a look. I could not find any documentation about when one must / must not call mdb_txn_abort. But in any case I do _not_ call txn_abort() twice. The problem rather seems to be that lmdb _implicitely_ frees invalid transactions. And my code then aborts them again _explicitely_. So mdb_abort was indeed called twice. Once in the MDB_TXN_ERROR internally in lmdb case and once from my code. On second thought my fix won't fix the same problem for errored child transactions. What is necessary seems to be either documenting on which error conditions the user needs to call txn_abort() and on which transactions (child vs parent, too). Or (what I would prefer) let the user clean up the transaction.
In case this is indeed already documented I would appreciate a pointer to the location of this documentation.
Thanks, Christopher