Add advisory for beamr: three classes of silent memory corruption (fixed in 0.16.3) - #3122
Open
tomWhiting wants to merge 1 commit into
Open
Add advisory for beamr: three classes of silent memory corruption (fixed in 0.16.3)#3122tomWhiting wants to merge 1 commit into
tomWhiting wants to merge 1 commit into
Conversation
Member
|
Please edit down your LLM-generated drivel both in the PR description and in the advisory. It should contain just a few sentences/paragraphs explaining the root cause of the issue, making it easy for downstream crate maintainers to understand if they're affected. If there are different issues fixed in different releases, those probably merit different advisories. An issue that is not yet fixed in any release definitely merits a different advisory. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Re-filing #3121, which did not use the pull request template. Same advisory, template-conformant, with two corrections found while preparing this one (the
datefield and a reference link that would have 404'd).Affected crate(s)
beamr(3,135 recent downloads per crates.io)Not separately filed:
beamr-cli(94 recent) andbeamr-wasm(161 recent) areour own crates and are covered transitively by the
beamrrequirement.Links to upstream issue(s) or PR(s)
We are the upstream maintainers, so this is filed under CONTRIBUTING's
maintainer exemption rather than reported inbound. Upstream record:
CHANGELOG.md,0.16.2entry.Published to crates.io 2026-07-23T11:05:21Z (C1 GC refcount-release
walk, C2 ETS borrowed caller-heap terms).
https://github.com/ablative-io/beamr/blob/main/CHANGELOG.md
CHANGELOG.md,0.16.3entry.Published to crates.io 2026-07-28T15:09:08Z. (That entry heads itself
2026-07-29; the changelog dates in the maintainers' local zone, crates.ioin UTC. UTC is used throughout this advisory.)
Pinned deliberately: the document is linked as of
4055cbe, and its ownsweep base is
f684d60— that is where the audit's line coordinatesresolve, not
main, andf684d60predates the document itself by twentyminutes, so it is not a valid path for it.
https://github.com/ablative-io/beamr/blob/4055cbe/docs/design/beamr/briefs/evidence/aion-encode-gc-defect/asbytes-sweep/AUDIT.md
committed RED by design):
499c414— lane 1, own the bytes before the allocating call at all ninemechanical crossings (walls:
af8440b)9a19961— lane 2,binary_to_term/1,2own the source bytes up front,before the decode recursion (walls:
8f693c9)c7609b6— lane 3,jit_bs_get_binaryowns its bytes, allocatesuniformly, advances position pre-alloc (walls:
91d772d,f7d0372)2672fa0— lane 4, mutation-proven tripwire wallsv0.16.3=1a77d5c480a7d75e87dff13756431d2fac744592Severity
Silent memory corruption — no panic, no crash, no error return.
beamris a BEAM virtual machine with a per-process generational copyingcollector. A minor collection relocates live young-heap objects and then
zero-fills the vacated region, so a stale borrow of moved data reads zeros
presented as valid data rather than faulting. A passing test suite is not
evidence of non-exposure.
Three classes, all fixed as of
0.16.3:as_bytesborrow-across-allocation. A helper returned&'static [u8]borrowed from garbage-collected process-heap memory;consumers held it across a call that could collect and then read through
it. Eleven real crossings, nine of them BIF sites reachable from ordinary
Erlang/Gleam string and binary operations (
string:trim/2,split/3,find/2,pad/4,slice/3,binary:part/3,uri_string:parse/1,erlang:'++'/2), plusbinary_to_term/1,2and a JIT binary-match helper.0.16.2) — inferred object type fromword[0]and could callArc::from_rawon a heap-cons payload: arbitraryfree plus heap corruption at the next minor GC.
0.16.2) that outlivedthe heap they pointed into.
Reaching class 1 requires no unsafe code and no unusual configuration —
the affected operations are ordinary string and binary BIFs invoked by
compiled bytecode. Observed under forced collection geometry:
binary:part(<<1..40>>, 10, 20)returned twenty zero bytes.On the affected range
patched = [">= 0.16.3"]with nounaffectedbound, deliberately.Our own changelog previously said "if you are on 0.16.0 or 0.16.1" — 56
versions are published and it named two. Preparing this advisory is what
caught it. Measured: the file carrying the borrow helper and all five
affected string BIFs is byte-identical — one blob hash,
d4054622d770886a7d91e1748cfd078d172206e3— across all 29 tags from0.4.4through
0.15.2, and at the0.16.2release commit67f89c4, which notag sweep could have reached because the
0.16.xline before0.16.3wasnever tagged. The helper's signature is present from
0.2.0(
string_bifs.rs:324). The introduction points of the two0.16.2-fixedclasses have not been measured, and the advisory says so rather than
implying a narrow range.
Scope note
The advisory text also mentions a separate JIT-reachable rooting class that
is still open and is publicly disclosed in our changelog. It is
deliberately not the subject of this advisory: it has no fix to point at, so
there is no
patchedrange to state. It is named only so that upgrading to0.16.3is not read as a clean bill of health. We expect to file itseparately once the fix lands.
Happy to adjust categories, wording, or split this into per-class advisories.
Checklist
RUSTSEC-0000-0000as the IDdatefield is set to the public disclosure date —2026-07-23, the0.16.2release that first publicly described classes 2 and 3. Class 1followed on
2026-07-28with0.16.3; because one field cannot carrytwo dates, the advisory body has a Disclosure timeline section
naming both. The earlier date is used so the advisory never understates
how long any covered class has been public.
the maintainers; filed by us under CONTRIBUTING's maintainer exemption