]> git.ipfire.org Git - thirdparty/openldap.git/commitdiff
ITS#10521 LMDB: fix mdb_txn_begin
authorHoward Chu <hyc@openldap.org>
Wed, 10 Jun 2026 19:32:41 +0000 (20:32 +0100)
committerHoward Chu <hyc@openldap.org>
Wed, 10 Jun 2026 19:34:05 +0000 (20:34 +0100)
Don't allow read txns to have child txns. Broken by ITS#10395.
Simplify the conditional tests to make it obvious.

libraries/liblmdb/mdb.c

index dba987f48b85ed18134de5cd35c5134ed75219f1..bd04edc1beebc3b268e4a662fc93dc0c28f081d9 100644 (file)
@@ -3496,16 +3496,17 @@ mdb_txn_begin(MDB_env *env, MDB_txn *parent, unsigned int flags, MDB_txn **ret)
                 * if the nested txn is a write txn there may only be 1, no writemap;
                 * if the nested txn is a read txn there may be arbitrarily many.
                 */
+               if (parent->mt_flags & MDB_TXN_RDONLY)
+                       return EINVAL;
+               if (parent->mt_flags & MDB_TXN_BLOCKED)
+                       return MDB_BAD_TXN;
+               if ((parent->mt_flags & MDB_TXN_WRITEMAP) && !(flags & MDB_RDONLY))
+                       return EINVAL;
                pthread_mutex_lock(&parent->mt_child_mutex);
                flags |= parent->mt_flags;
                if (parent->mt_child && F_ISSET(parent->mt_child->mt_flags, MDB_RDONLY) && F_ISSET(flags, MDB_RDONLY)) {
                        flags &= ~MDB_TXN_HAS_CHILD;
                }
-               if ((F_ISSET(flags, MDB_WRITEMAP) && !F_ISSET(flags, MDB_RDONLY)) || F_ISSET(flags, MDB_TXN_BLOCKED)) {
-                       flags = parent->mt_flags;
-                       pthread_mutex_unlock(&parent->mt_child_mutex);
-                       return (flags & MDB_TXN_RDONLY) ? EINVAL : MDB_BAD_TXN;
-               }
                pthread_mutex_unlock(&parent->mt_child_mutex);
                /* Child txns save MDB_pgstate and use own copy of cursors */
                size = env->me_maxdbs * (sizeof(MDB_db)+sizeof(MDB_cursor *)+1);