Skip to content

feat: add a leanchecker-paranoid binary with mimalloc mitigations - #14884

Open
Kha wants to merge 1 commit into
masterfrom
leanchecker-paranoid
Open

feat: add a leanchecker-paranoid binary with mimalloc mitigations#14884
Kha wants to merge 1 commit into
masterfrom
leanchecker-paranoid

Conversation

@Kha

@Kha Kha commented Aug 21, 2026

Copy link
Copy Markdown
Member

This PR adds bin/leanchecker-paranoid, a variant of leanchecker built with allocator hardening.

leanchecker-paranoid is built with mimalloc's memory-safety mitigations at MI_SECURE=3. Level 3 enables encoded free lists and the padding they imply. Encoding is the part that matters for Lean: lean_object.m_rc sits at offset 0, exactly where mimalloc keeps a freed block's free-list link, so a reference-count operation through a stale pointer writes into allocator metadata rather than into dead payload. Over 40 runs of a probe modelling that, level 3 eliminates uncontrolled crashes entirely and converts them into a checked abort raised before a bad block is handed out. Padding additionally catches out-of-bounds constructor and array writes. The cost is roughly +26% wall-clock and +17.5% heap size.

The binary is not exposed by elan; instead, it will be directly integrated into upcoming checker workflows.

This PR adds `leanchecker-paranoid`, a variant of `leanchecker` whose allocator is built with mimalloc's memory-safety mitigations at `MI_SECURE=3`. It is not built by default; release CI builds it explicitly so it ships alongside the ordinary binary, which is unaffected.

Level 3 enables encoded free lists and the padding they imply. Encoding is the part that matters for Lean: `lean_object.m_rc` sits at offset 0, exactly where mimalloc keeps a freed block's free-list link, so a reference-count operation through a stale pointer writes into allocator metadata rather than into dead payload. Over 40 runs of a probe modelling that, level 3 eliminates uncontrolled crashes entirely and converts them into a checked abort raised before a bad block is handed out. Padding additionally catches out-of-bounds constructor and array writes. The cost is roughly +26% wall and +17.5% of the live heap, paid by no other binary.

The binary has to be linked statically: `leanshared` owns the allocator of every dynamically linked binary and is linked `-Bsymbolic`, so its internal `mi_*` calls cannot be redirected from an executable. Only mimalloc's own translation unit depends on `MI_SECURE`, so `add_mimalloc_variant` compiles it once per (mitigation level, TLS model) the build needs and each runtime archive consumes the matching object. Those flags cannot live on the shared source instead, because source properties are directory-scoped and CMake emits them after target options, so a per-target override would silently lose.

`-rdynamic` is dropped here through the new `CMAKE_DYN_EXE_LINKER_FLAGS`, which collects the flags only dynamically linked binaries want; it exists for the interpreter, and on a static binary it defeats `--gc-sections` and inflates the symbol tables. With it gone and the binary stripped, the result is 78 MB on disk and about 19 MiB compressed.

Finally, the hardened mimalloc wins only because its archive precedes `-lleanrt`. A disturbed order would link successfully with no mitigations and no diagnostic, so the link rule asserts the property on the finished binary and fails the build if it is missing.
@Kha Kha added the release-ci Enable all CI checks for a PR, like is done for releases label Aug 21, 2026
@Kha
Kha requested a review from kim-em as a code owner August 21, 2026 15:55
@github-actions github-actions Bot added the toolchain-available A toolchain is available for this PR, at leanprover/lean4-pr-releases:pr-release-NNNN label Aug 21, 2026
@mathlib-lean-pr-testing

Copy link
Copy Markdown

Mathlib CI status (docs):

  • ❗ Batteries/Mathlib CI will not be attempted unless your PR branches off the nightly-with-mathlib branch. Try git rebase f8facdb3303012c0d6806661867fc86e68234641 --onto 16e77c407779fde9a649adf3478204d1915371a3. You can force Mathlib CI using the force-mathlib-ci label. (2026-08-21 17:04:51)

@leanprover-bot

Copy link
Copy Markdown
Collaborator

Reference manual CI status:

  • ❗ Reference manual CI will not be attempted unless your PR branches off the nightly-with-manual branch. Try git rebase f8facdb3303012c0d6806661867fc86e68234641 --onto 16e77c407779fde9a649adf3478204d1915371a3. You can force reference manual CI using the force-manual-ci label. (2026-08-21 17:04:52)

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

Labels

changelog-other release-ci Enable all CI checks for a PR, like is done for releases toolchain-available A toolchain is available for this PR, at leanprover/lean4-pr-releases:pr-release-NNNN

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants