From: Hallvard Furuseth Date: Tue, 25 Jul 2017 19:27:36 +0000 (+0200) Subject: Protect freelist at end of mdb_freelist_save() X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=6dd5a4d7f6ba65047508a9de808b8e8adddd8d39;p=thirdparty%2Fopenldap.git Protect freelist at end of mdb_freelist_save() --- diff --git a/libraries/liblmdb/mdb.c b/libraries/liblmdb/mdb.c index 05273a25ab..8229b1fdf9 100644 --- a/libraries/liblmdb/mdb.c +++ b/libraries/liblmdb/mdb.c @@ -3696,11 +3696,17 @@ mdb_freelist_save(MDB_txn *txn) mop_len = mop[0]; } - /* Fill in the reserved me_pghead records */ + /* Fill in the reserved me_pghead records. Everything is finally + * in place, so this will not allocate or free any DB pages. + */ rc = MDB_SUCCESS; if (mop_len) { MDB_val key, data; + /* Protect DB env from any (buggy) freelist use when saving mop */ + env->me_pghead = NULL; + txn->mt_dirty_room = 0; + mop += mop_len; rc = mdb_cursor_first(&mc, &key, &data); for (; !rc; rc = mdb_cursor_next(&mc, &key, &data, MDB_NEXT)) { @@ -3714,14 +3720,17 @@ mdb_freelist_save(MDB_txn *txn) len = mop_len; data.mv_size = (len + 1) * sizeof(MDB_ID); } + mop_len -= len; data.mv_data = mop -= len; save = mop[0]; mop[0] = len; rc = mdb_cursor_put(&mc, &key, &data, MDB_CURRENT); mop[0] = save; - if (rc || !(mop_len -= len)) + if (rc || !mop_len) break; } + + env->me_pghead = mop - mop_len; } /* Restore this so we can check vs. dirty_list after mdb_page_flush() */