[Date Prev][Date Next] [Chronological] [Thread] [Top]

Re: (ITS#9097) lmdb: premature free of env->me_txn0



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



-- 
http://gmerlin.de
OpenPGP: http://gmerlin.de/christopher.pub
CB07 DA40 B0B6 571D 35E2  0DEF 87E2 92A7 13E5 DEE1