[IR] Add !sensitive metadata for sensitive stack objects - #3
Draft
claude[bot] wants to merge 1 commit into
Draft
Conversation
|
|
claude
Bot
force-pushed
the
zeroize-intrinsic
branch
from
August 11, 2026 16:33
68b8fec to
0bd0b1b
Compare
claude
Bot
force-pushed
the
sensitivity-metadata
branch
from
August 11, 2026 16:33
a19500d to
ce6cbab
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.
Register a fixed metadata kind marking an alloca whose contents should not be left readable in the stack frame once the function is done with them. The metadata is only used as a flag: its presence on the alloca is the entire signal and the node must be empty, with the contents of the node reserved for future use. The marked objects are what the "sensitive" mode of the "zeroize-stack" attribute clears, so the LangRef entry is written around the direction of the fallback between the two. The metadata buys precision and is not itself part of the guarantee. Dropping it is always permitted, and where the marked set has stopped describing the frame the response is to clear more, at the limit every stack slot the function used, never to clear less. Absence of the metadata on an object is not a statement that the object is insensitive, and a transform may not shrink the set of objects a function clears on the strength of what is or is not marked. What makes losing the metadata safe is that the mode's floor already covers every frame object with no source-level provenance, such as spill slots, the callee-save area and alignment padding, whether or not anything is marked. Parsing, printing and bitcode serialization of metadata attachments are generic, so the round-trip test needs no new parser code; registering the kind gives consumers a fixed ID to look the attachment up by. No pass or backend reads the metadata yet, and which transforms should carry it across the objects they create is left to a later change. The name is a recommendation still awaiting sign-off on trailofbits/vspells-ct-internal-notes#64.
claude
Bot
force-pushed
the
zeroize-intrinsic
branch
from
August 11, 2026 19:57
0bd0b1b to
f01c5be
Compare
claude
Bot
force-pushed
the
sensitivity-metadata
branch
from
August 11, 2026 19:57
ce6cbab to
6099f1a
Compare
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
Register a fixed metadata kind,
MD_sensitivewith ID 56, marking anallocawhose contents should not be left readable in the stack frame once the function
is done with them. The metadata is only used as a flag: its presence on the
allocais the entire signal and the node must be empty, with the contents ofthe node reserved for future use.
The marked objects are what the
"sensitive"mode of the"zeroize-stack"attribute clears, so the LangRef entry is written around the direction of the
fallback between the two, and the attribute entry now cross-references it
instead of referring to "sensitivity metadata" without naming it. The metadata
buys precision and is not itself part of the guarantee, which LangRef spells out
as rules a transform has to respect: dropping the metadata is always permitted,
and where the marked set has stopped describing the frame — a marked object
split, merged, replaced or promoted without the metadata following — the
response is to clear more, at the limit every stack slot the function used, never
to clear less. Attaching it to an object that was not marked before is likewise
permitted and can only widen what is cleared. Absence of the metadata is not a
statement that an object is insensitive, so a transform may not shrink the set
of objects a function clears on the strength of what is or is not marked.
What makes losing the metadata safe is the floor the mode already has: it clears
every frame object whose contents cannot be traced back to a source-level object
— spill slots, the callee-save area, alignment padding — whether or not anything
is marked. Those are exactly the places a copy of marked data can land with
nothing recording where it came from.
Parsing, printing and bitcode serialization of metadata attachments are generic,
so nothing in the parser or the bitcode reader and writer needed changing;
registering the kind is what gives consumers a fixed ID to look the attachment up
by.
llvm/test/Assembler/sensitive-metadata.llcovers the textual and bitcoderound-trips, alongside the comparable per-kind assembler tests
associated-metadata.llandnoalias-addrspace-md.ll.No pass or backend reads the metadata yet, and nothing here changes the
behaviour of any existing pass. Which transforms should be taught to carry the
metadata across the objects they create is scoped separately as
trailofbits/vspells-ct-internal-notes#13; LangRef says that propagation is a
question of precision rather than of correctness, which is what makes it safe to
defer.
The spellings
!sensitiveand"zeroize-stack"are recommendations stillawaiting sign-off on trailofbits/vspells-ct-internal-notes#64, not ratified
names.
Third change in the wave-1 stack, on top of
zeroize-intrinsic. Implementstrailofbits/vspells-ct-internal-notes#12.
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