fix(l1): keep global_asm! blocks from leaking their section state - #7248
fix(l1): keep global_asm! blocks from leaking their section state#7248MegaRedHand wants to merge 2 commits into
global_asm! blocks from leaking their section state#7248Conversation
`keccak1600-x86_64.s` ends with a `.section .note.gnu.property` block for the CET flags and never switches back. Blocks emitted by `global_asm!` share the assembler's section state within a codegen unit, so whichever block rustc places next continues in that note section: on Rust 1.99-beta the blake2f AVX2 block lands there, putting `_blake2b_f` in a non-executable NOTE section. That the previous ordering worked was luck, not a compiler guarantee, so fix it on our side: wrap the note block in `.pushsection`/`.popsection`, and make each block declare `.text` up front instead of inheriting whatever section it starts in. The x86_64 keccak file already did the latter; the ARMv8 files and the blake2f file did not. Closes #7246
|
🤖 Kimi Code ReviewI'll review this PR which addresses issue #7246 regarding SummaryThis PR fixes a subtle but serious codegen bug where Detailed Review1. Core Fix Correctness —
|
| Aspect | Status |
|---|---|
| Code injection via wrong section | Mitigated — .pushsection/.popsection prevents leakage |
| W^X violations | Prevented — functions won't land in non-executable note sections |
| Supply chain (asm provenance) | Documented — modifications clearly tracked |
Recommendations
-
Consider a macro/wrapper (future PR): For new assembly additions, consider a Rust-side wrapper that enforces
.text+.popsectionpatterns, or add a CI check that validatesglobal_asm!files for section hygiene. -
Verify no other asm files affected: Search for other
.sectiondirectives inglobal_asm!usage:grep -r "\.section" crates/common/crypto/ --include="*.s" | grep -v pushsection | grep -v popsection
Verdict
Approve. This is a correct, minimal fix for a subtle codegen bug. The .pushsection/.popsection pattern is the standard solution for this problem, and the explicit .text entries make the code robust against ordering changes in codegen units.
Automated review by Kimi (Moonshot AI) · kimi-k2.6 · custom prompt
🤖 Claude Code ReviewThis is a small, well-targeted assembly fix. Verified the diffs against the actual files. ReviewCorrectness of the fix
Verification The PR description shows a concrete, reproduced before/after ( Minor notes
No correctness, security, or gas-accounting concerns — this only affects linking of the crypto backend, not EVM semantics. Nothing here needs to change before merge. Automated review by Claude (Anthropic) · sonnet · custom prompt |
🤖 Codex Code ReviewFindings
Static review looks good. The change is narrowly scoped and appears to fix the actual failure mode: crates/common/crypto/keccak/keccak1600-x86_64.s now restores the previous section after emitting I did not find correctness, security, gas-accounting, or maintainability concerns from this patch itself. I could not run Automated review by OpenAI Codex · gpt-5.4 · custom prompt |
There was a problem hiding this comment.
Pull request overview
Fixes a build/link failure caused by global_asm! blocks sharing the assembler’s “current section” within a single codegen unit, which could cause subsequent assembly blocks to accidentally emit code into .note.gnu.property instead of .text.
Changes:
- Prevent
keccak1600-x86_64.sfrom leaking.note.gnu.propertysection state by using.pushsection/.popsection. - Make embedded assembly blocks more robust by explicitly switching to
.textin additional assembly sources. - Update keccak documentation to reflect that both x86 and ARM assembly sources require local modifications for
global_asm!inclusion.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| crates/common/crypto/keccak/README.md | Documents the required .text / section-state discipline for global_asm!-included assembly. |
| crates/common/crypto/keccak/keccak1600-x86_64.s | Wraps the trailing .note.gnu.property block in .pushsection/.popsection to avoid leaking section state. |
| crates/common/crypto/keccak/keccak1600-armv8-macho.s | Adds an explicit .text directive so the block doesn’t inherit a prior section. |
| crates/common/crypto/keccak/keccak1600-armv8-elf.s | Adds an explicit .text directive so the block doesn’t inherit a prior section. |
| crates/common/crypto/blake2f/x86_64.s | Adds an explicit .text directive to ensure the function is emitted into the text section. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Motivation
keccak1600-x86_64.sends with a.section .note.gnu.propertyblock carrying the CETfeature flags, and never switches back to
.text. Blocks emitted byglobal_asm!share theassembler's section state within a codegen unit, so whichever block rustc places after it keeps
emitting into that note section.
On Rust 1.99-beta that next block is the blake2f AVX2 implementation, so
_blake2b_fisdefined inside a non-executable
NOTEsection. The link then fails:(lld parses
.note.gnu.propertyto compute the output's GNU property bits, and walks off theend of what it thinks is a note once ~5 KiB of blake2f code is sitting in there.)
As @cuviper points out in #7246, this is not really a compiler regression: nothing guarantees
an ordering between
global_asm!blocks, and the old ordering working was luck. Confirmed:on stable rustc emits the blake2f block first, which is the only reason the stray section
state never reached it.
This affects release builds specifically.
[profile.release]setscodegen-units = 1,which is what puts both blocks in the same codegen unit; the default multi-CGU split used by
debug and
cargo testbuilds happens to separate them, and those are unaffected on eithertoolchain.
Description
keccak1600-x86_64.s: wrap the trailing note block in.pushsection/.popsectionso itrestores the previous section instead of leaking it. This is the fix for Rust 1.99-beta regression due to
global_asm!section change #7246, and is whatthe issue suggests.
global_asm!block declare.textup front rather than inheriting whateversection it happens to start in, so the pairing is robust in both directions:
blake2f/x86_64.s,keccak1600-armv8-elf.s,keccak1600-armv8-macho.s. (The x86_64 keccakfile already opened with
.text.) These three are defensive, not required to close the issue.Modified:header, and update the keccakREADME.md, whichclaimed the x86 file was imported unmodified.
No functional change to any of the assembly itself.
Verification
Reproduced and fixed on an x86_64 Linux host (
stable1.92.0 vsbeta1.99.0-beta.3, linkingthrough the host
ccwith-fuse-ld=lld), building the realethrex-cryptocrate:_blake2b_flands in.note.gnu.propertysize.text0x20.note.gnu.property0x13c0.text0x20.text0x20The failure:
The section column above comes from unpacking the rlib and reading the symbol table, which is
worth doing on the base commit even where the link succeeds, since it shows the note section
ballooning from its correct
0x20bytes to0x13c0:codegen-units = 1is required to reproduce. Plaincargo testuses thetestprofile(inheriting
[profile.dev]), where rustc's default multi-CGU split places the keccak andblake2f
global_asm!blocks in different codegen units, so the leaked section state neverreaches blake2f. For the record, on the same host
cargo +stable test --no-runandcargo +beta test --no-runover the whole workspace both exit 0 on the pre-fix base as well ason this PR — those commands alone do not exercise the bug.
aarch64 cannot hit this at all: neither ARMv8 file contains a
.note.gnu.propertyblock, sothe
.textadded to them is purely defensive. Checked regardless on aarch64-apple-darwin —full-workspace
cargo test --no-runon both stable and beta, plus the keccak suite(
crypto::keccak_tests, 11 tests) — all green.Checklist
Updated
STORE_SCHEMA_VERSION(crates/storage/lib.rs) if the PR includes breaking changes to theStorerequiring a re-sync.Not applicable: assembly and documentation only, no
Storechanges.Closes #7246