diff -urp lmdb-LMDB_0.9.23.orig/libraries/liblmdb/mdb.c lmdb-LMDB_0.9.23/libraries/liblmdb/mdb.c
--- lmdb-LMDB_0.9.23.orig/libraries/liblmdb/mdb.c	2020-03-07 14:26:45.686882948 -0500
+++ lmdb-LMDB_0.9.23/libraries/liblmdb/mdb.c	2020-03-08 23:29:02.514325490 -0400
@@ -2683,6 +2683,8 @@ mdb_txn_renew0(MDB_txn *txn)
 	if ((flags &= MDB_TXN_RDONLY) != 0) {
 		if (!ti) {
 			meta = mdb_env_pick_meta(env);
+			if (meta == NULL)
+				return MDB_CORRUPTED;
 			txn->mt_txnid = meta->mm_txnid;
 			txn->mt_u.reader = NULL;
 		} else {
@@ -2752,6 +2754,8 @@ mdb_txn_renew0(MDB_txn *txn)
 			meta = env->me_metas[txn->mt_txnid & 1];
 		} else {
 			meta = mdb_env_pick_meta(env);
+			if (meta == NULL)
+				return MDB_CORRUPTED;
 			txn->mt_txnid = meta->mm_txnid;
 		}
 		txn->mt_txnid++;
@@ -3938,6 +3942,8 @@ static MDB_meta *
 mdb_env_pick_meta(const MDB_env *env)
 {
 	MDB_meta *const *metas = env->me_metas;
+	if (metas == NULL || metas[0] == NULL || metas[1] == NULL)
+		return NULL;
 	return metas[ metas[0]->mm_txnid < metas[1]->mm_txnid ];
 }
 
@@ -4063,6 +4069,8 @@ mdb_env_set_mapsize(MDB_env *env, size_t
 		if (env->me_txn)
 			return EINVAL;
 		meta = mdb_env_pick_meta(env);
+		if (meta == NULL)
+			return MDB_CORRUPTED;
 		if (!size)
 			size = meta->mm_mapsize;
 		{
@@ -4387,8 +4395,15 @@ mdb_env_open2(MDB_env *env)
 #endif
 
 	if ((i = mdb_env_read_header(env, &meta)) != 0) {
+		unsigned int psize;
+
 		if (i != ENOENT)
 			return i;
+
+		GET_PAGESIZE(psize);
+		if (psize != env->me_os_psize)
+			return MDB_CORRUPTED;
+
 		DPUTS("new mdbenv");
 		newenv = 1;
 		env->me_psize = env->me_os_psize;
@@ -4401,6 +4416,12 @@ mdb_env_open2(MDB_env *env)
 		env->me_psize = meta.mm_psize;
 	}
 
+	/* Farther down, we will get a division by zero. This only happens
+	 * if the db is corrupted
+	 */
+	if (env->me_psize == 0)
+		return MDB_CORRUPTED;
+
 	/* Was a mapsize configured? */
 	if (!env->me_mapsize) {
 		env->me_mapsize = meta.mm_mapsize;
@@ -4453,6 +4474,8 @@ mdb_env_open2(MDB_env *env)
 #if MDB_DEBUG
 	{
 		MDB_meta *meta = mdb_env_pick_meta(env);
+		if (meta == NULL)
+			return MDB_CORRUPTED;
 		MDB_db *db = &meta->mm_dbs[MAIN_DBI];
 
 		DPRINTF(("opened database version %u, pagesize %u",
@@ -4550,6 +4573,8 @@ mdb_env_share_locks(MDB_env *env, int *e
 {
 	int rc = 0;
 	MDB_meta *meta = mdb_env_pick_meta(env);
+	if (meta == NULL)
+		return MDB_CORRUPTED;
 
 	env->me_txns->mti_txnid = meta->mm_txnid;
 
@@ -5279,7 +5304,9 @@ mdb_node_search(MDB_cursor *mc, MDB_val
 	MDB_cmp_func *cmp;
 	DKBUF;
 
-	nkeys = NUMKEYS(mp);
+	nkeys = NUMKEYS(mp); /* FIXME: this needs sanity checking. it can lead
+				to integer overflow at i = (low + high) >> 1;
+				and a SEGV on NODEPTR in the else branch */
 
 	DPRINTF(("searching %u keys in %s %spage %"Z"u",
 	    nkeys, IS_LEAF(mp) ? "leaf" : "branch", IS_SUBP(mp) ? "sub-" : "",
@@ -6935,6 +6962,8 @@ current:
 
 new_sub:
 	nflags = flags & NODE_ADD_FLAGS;
+	if (mc->mc_pg[mc->mc_top] == NULL)
+		return MDB_CORRUPTED;
 	nsize = IS_LEAF2(mc->mc_pg[mc->mc_top]) ? key->mv_size : mdb_leaf_size(env, key, rdata);
 	if (SIZELEFT(mc->mc_pg[mc->mc_top]) < nsize) {
 		if (( flags & (F_DUPDATA|F_SUBDATA)) == F_DUPDATA )
@@ -7276,7 +7305,14 @@ mdb_node_add(MDB_cursor *mc, indx_t indx
 	void		*ndata;
 	DKBUF;
 
-	mdb_cassert(mc, mp->mp_upper >= mp->mp_lower);
+	/* This assert should really be turned into an error code. This
+	 * will crash any application without it being able to safely
+	 * close its files. */
+	//mdb_cassert(mc, mp->mp_upper >= mp->mp_lower);
+	if (mp->mp_upper < mp->mp_lower) {
+		mc->mc_txn->mt_flags |= MDB_TXN_ERROR;
+		return MDB_CORRUPTED;
+	}
 
 	DPRINTF(("add to %s %spage %"Z"u index %i, data size %"Z"u key size %"Z"u [%s]",
 	    IS_LEAF(mp) ? "leaf" : "branch",
@@ -9675,6 +9711,8 @@ mdb_env_stat(MDB_env *env, MDB_stat *arg
 		return EINVAL;
 
 	meta = mdb_env_pick_meta(env);
+	if (meta == NULL)
+		return MDB_CORRUPTED;
 
 	return mdb_stat0(env, &meta->mm_dbs[MAIN_DBI], arg);
 }
@@ -9688,6 +9726,8 @@ mdb_env_info(MDB_env *env, MDB_envinfo *
 		return EINVAL;
 
 	meta = mdb_env_pick_meta(env);
+	if (meta == NULL)
+		return MDB_CORRUPTED;
 	arg->me_mapaddr = meta->mm_address;
 	arg->me_last_pgno = meta->mm_last_pg;
 	arg->me_last_txnid = meta->mm_txnid;
@@ -10239,6 +10279,11 @@ mdb_mutex_failed(MDB_env *env, mdb_mutex
 			 * overwrite data which latest meta page refers to.
 			 */
 			meta = mdb_env_pick_meta(env);
+			if (meta == NULL) {
+				env->me_flags |= MDB_FATAL_ERROR;
+				env->me_txn = NULL;
+				return MDB_CORRUPTED;
+			}
 			env->me_txns->mti_txnid = meta->mm_txnid;
 			/* env is hosed if the dead thread was ours */
 			if (env->me_txn) {
