[IR] Add the "zeroize-stack" function attribute - #1
Open
claude[bot] wants to merge 1 commit into
Open
Conversation
Define a string function attribute requesting that a function clear its stack frame before returning, so that data the frame held is not left readable to whatever runs on those addresses next. The attribute takes a required mode: "used" clears every stack slot the function used, and "sensitive" clears the slots that sensitivity metadata identifies plus every slot whose contents cannot be traced back to a source-level object. The fallback between the two modes is deliberately one-directional. Passes are free to drop sensitivity metadata, and once it is gone the remaining obligation is "used", so losing the metadata only ever widens what gets cleared and never narrows it. An unrecognized mode value is treated as "used" for the same reason. No consumer reads the attribute yet. Parsing and printing are generic for string function attributes, so the round-trip test covers them without any new parser code. How the attribute constrains inlining is left to a later change. The names are recommendations still awaiting sign-off on trailofbits/vspells-ct-internal-notes#64.
|
|
claude
Bot
force-pushed
the
zeroize-stack-attribute
branch
from
August 11, 2026 16:33
66b3ca1 to
a50c171
Compare
kumarak
added a commit
that referenced
this pull request
Aug 11, 2026
Emit the two IR function attributes a protected function needs: "zero-call-used-regs"="all" for register clearing and the new "zeroize-stack"="used" for stack clearing. The register attribute is the existing one, reused unchanged. Pinning it to "all" rather than one of the "used" modes is deliberate: the used-register computation ignores implicit operands and so misses registers defined only implicitly, which is acceptable for a hardening option and not for an obligation over machine state. The lowering runs after the zero_call_used_regs block so that it wins over both the command-line mode and an explicit zero_call_used_regs on the same function. The attribute's guarantee is a minimum that other policy may widen but not narrow. Unlike zero_call_used_regs, the requests are not stamped onto call sites. They describe the callee's own frame and its exits, and putting them on a call instruction would suggest the call site clears something. An explicitly annotated main keeps both requests. The existing exemption that strips the command-line default from main is narrowed rather than removed, so an un-annotated main is unaffected. ClangIR emits the same requests, which needs a zeroize_stack field on LLVM::LLVMFuncOp and the underscore-to-dash conversion in the MLIR translator. -fzero-call-used-regs behaviour is unchanged throughout, which the existing zero-call-used-regs tests pin. Part of #1. Closes #3.
kumarak
marked this pull request as ready for review
August 11, 2026 23:41
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.
Requested by Francesco Bertolaccini · Slack thread
Define a string function attribute requesting that a function clear its stack
frame before returning, so that data the frame held is not left readable to
whatever runs on those addresses next. The attribute takes a required mode:
"used"clears every stack slot the function used, and"sensitive"clears theslots that sensitivity metadata identifies plus every slot whose contents cannot
be traced back to a source-level object. The second half of
"sensitive"is notoptional: spill slots, the callee-save area and alignment padding can all hold
copies of marked data, and nothing records where those copies came from.
The fallback between the two modes is deliberately one-directional. Passes are
free to drop sensitivity metadata, and once it is gone the remaining obligation
is
"used", so losing the metadata only ever widens what gets cleared and nevernarrows it. An unrecognized mode value is treated as
"used"for the samereason.
No consumer reads the attribute yet, and it needs no parser or printer code:
parsing and printing are generic for string function attributes, so
llvm/test/Assembler/zeroize-stack.llcovers the textual and bitcoderound-trips on its own.
"zero-call-used-regs"is modelled the same way — itappears in no parser, printer or attribute-definition file, and is decoded on
demand at its single consumption site in
PrologEpilogInserter.cppvia aStringSwitch— and it gains its mode enum in the same patch as that consumer.Adding one here ahead of a consumer would be unused code.
How the attribute constrains inlining is left to
trailofbits/vspells-ct-internal-notes#14; the LangRef entry states the invariant
a transform must preserve and defers the inlining rule rather than asserting
one. That change needs to land before any backend consumer of this attribute:
until it does, the inliner will fold a
"zeroize-stack"callee into anunprotected caller and drop the obligation silently, which is inert while
nothing reads the attribute and becomes a miscompile the moment something does.
The names here are recommendations still awaiting sign-off on
trailofbits/vspells-ct-internal-notes#64. Nothing in this change makes a rename
hard: the attribute string appears only in the LangRef entry and the test.
Closes trailofbits/vspells-ct-internal-notes#9.
AI tool use
This pull request contains AI-generated content. It was prepared with the assistance of Claude Code; the contributor has reviewed the generated code and text, is the author of the contribution, and is accountable for it, per the LLVM AI Tool Use Policy.
Generated by Claude Code