Skip to content

fix: drop MDB_WRITEMAP to avoid LMDB freelist assertion crash - #3639

Merged
airween merged 1 commit into
owasp-modsecurity:v3/masterfrom
fzipi:fix-lmdb-writemap-freelist-crash
Sep 20, 2026
Merged

airween merged 1 commit into
owasp-modsecurity:v3/masterfrom
fzipi:fix-lmdb-writemap-freelist-crash

Conversation

@fzipi

@fzipi fzipi commented Sep 20, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

The macOS (with lmdb) CI job fails deterministically on test/test-cases/regression/action-expirevar.json and test/test-cases/regression/issue-1831.json with:

mdb.c:3900: Assertion 'x <= dl[0].mid' failed in mdb_freelist_save()

This reproduces with a minimal standalone LMDB program with no ModSecurity code involved: a get/del/put/commit cycle on a key, interleaved with a read-only get and a delete-only commit, crashes mdb_freelist_save() when the environment is opened with MDB_WRITEMAP.

The failing assertion is in the mt_loose_pgs/dirty-list reconciliation loop inside mdb_freelist_save(), which only executes if (txn->mt_flags & MDB_TXN_WRITEMAP). This guard is still present at the current tip of LMDB's own mdb.RE/1.0 branch, so it is not fixed by upgrading LMDB.

Apple Silicon macOS uses a 16KB page size (sysctl hw.pagesize), versus 4KB on the Linux CI runners. The Linux with lmdb jobs use liblmdb-dev 0.9.24 from Ubuntu and pass; the macOS job installs whatever Homebrew's lmdb formula currently resolves to (1.0.2 at the time of this PR). The same C++ code path is exercised on both platforms; only the macOS job fails, consistently, across multiple runs and multiple unrelated commits on v3/master.

Change

src/collection/backend/lmdb.cc: mdb_env_open() no longer passes MDB_WRITEMAP, only MDB_NOSUBDIR.

Test plan

  • Reproduced the crash with a standalone LMDB C program (no ModSecurity involved), confirmed it disappears when MDB_WRITEMAP is removed from mdb_env_open, using the same environment (LMDB 1.0.2 via Homebrew, arm64 macOS).
  • Built v3/master plus this one-line change locally with ./configure --with-lmdb --enable-assertions=yes and make.
  • make check: 5043 total, 5025 pass, 18 skip, 0 fail (previously 3 failures, all in the two files above, both LMDB-collection related).
  • Ran action-expirevar.json and issue-1831.json individually, all sub-tests pass.

Summary by CodeRabbit

  • Bug Fixes
    • Updated database access behavior to open LMDB files without write-map semantics, improving compatibility with environments where memory-mapped writes are unavailable.
The macOS (with lmdb) CI job crashed deterministically in
action-expirevar.json and issue-1831.json with:

  mdb.c:3900: Assertion 'x <= dl[0].mid' failed in mdb_freelist_save()

Reproduced with a minimal standalone LMDB program (no ModSecurity code
involved): a get/del/put/commit cycle on the same key, interleaved with
a read-only get and a delete-only commit, crashes LMDB's
mdb_freelist_save() when the environment is opened with MDB_WRITEMAP.
The failing assertion is in the mt_loose_pgs/dirty-list reconciliation
loop, which only runs "if (txn->mt_flags & MDB_TXN_WRITEMAP)" - this is
still present in LMDB's current upstream 1.0 branch, i.e. not something
fixed by upgrading. Apple Silicon's 16KB page size makes it far easier
to hit than Linux's 4KB pages, which is why only the macOS lmdb job
failed while Linux (same code, older liblmdb) passed.

Opening the environment without MDB_WRITEMAP avoids the buggy code
path entirely; the same repro runs cleanly, and the full test suite
now passes (previously 3 failures, all lmdb-collection related).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Sep 20, 2026 •

Copy link
Copy Markdown

Review Change StackReview Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Advanced

Run ID: d13ca6b9-80fb-418b-bda2-8c43a9a003b3

📥 Commits

Reviewing files that changed from the base of the PR and between 7ea9fef and 3ac2809.

📒 Files selected for processing (1)
  • src/collection/backend/lmdb.cc

Included review availability: Your plan provides up to 8 included reviews per hour; 7 remain after this review.


📝 Walkthrough

Walkthrough

The LMDB environment now opens the shared collection database with MDB_NOSUBDIR only. The MDB_WRITEMAP flag was removed from the mdb_env_open call.

Changes

LMDB open configuration

Layer / File(s) Summary
Disable write-map mode
src/collection/backend/lmdb.cc
The MDBEnvProvider constructor removes MDB_WRITEMAP from the mdb_env_open flags and keeps MDB_NOSUBDIR with mode 0664.

Priority: ➖ Normal

Estimated code review effort: 1 (Trivial) | ~2 minutes

Change: Bug fix

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 1 functions across 1 files. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: removing MDB_WRITEMAP to prevent the LMDB freelist assertion crash.
  • Fix all pre-merge checks with AI
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create a new PR

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@fzipi fzipi changed the title Drop MDB_WRITEMAP to avoid LMDB freelist assertion crash Sep 20, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟢 Approval recommended

The reported regression tests pass and the macOS crash is resolved.

Review effort: Lite
Findings: None

What changed in this PR

Removes LMDB write-map mode to prevent deterministic freelist assertion crashes on Apple Silicon macOS.

Changes:

  • Opens LMDB with MDB_NOSUBDIR only.
  • Preserves existing LMDB persistence behavior.
File Description
src/​collection/​backend/​lmdb.cc Removes MDB_WRITEMAP from LMDB environment initialization.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

@airween airween left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thank you!

@airween
airween merged commit 2dada4c into owasp-modsecurity:v3/master Sep 20, 2026
99 checks passed
@airween

airween commented Sep 20, 2026

Copy link
Copy Markdown
Member

Thank you, @fzipi!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

3 participants