-
Notifications
You must be signed in to change notification settings - Fork 10.6k
Add the experimental attribute @sensitive
for struct declarations
#72850
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
@swift-ci test |
Is there a way for this to be tied to a special kind of Cleanup so it can fall out of the compiler’s usual lifetime-related codegen? |
EFFECT(NoEffect), | ||
UNKNOWN_MEMEFFECTS) | ||
|
||
FUNCTION(MemsetS, memset_s, C_CC, AlwaysAvailable, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps this should be a stdlib-defined runtime function so different platforms can bring their own memset_s/memset_explicit/explicit_bzero/SecureZeroMemory
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right. This makes sense
If you are talking about cleanup in SILGen, this is not enough. First, zeroing must also be done for a "take" operation, not only for destroy at cleanup. Second, we need to do it in value witness functions, because a sensitive value can be passed as a generic parameter to a generic function. |
if (passIndirectToDirect) { | ||
llvm::Value *ptr = in.claimNext(); | ||
|
||
if (AI.getKind() == clang::CodeGen::ABIArgInfo::Indirect) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is the case where the SIL claimed the C function took it @in_guaranteed
(the callee preserves the content of the memory pointed to).
We pass the pointer to a C function that that lowers that argument indirect. It depends on the platform ABI whether the callee may modify that memory or not.
You need to create a temporary copy unless there would be some other guarantee in SIL that the SIL address passed to the C function call is not used after the call.
FUNCTION(MemsetS, memset_s, C_CC, AlwaysAvailable, | ||
RETURNS(Int32Ty), | ||
ARGS(PtrTy, SizeTy, Int32Ty, SizeTy), | ||
ATTRS(NoUnwind), | ||
EFFECT(NoEffect), | ||
UNKNOWN_MEMEFFECTS) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did you mean to leave the memset_s
declaration here as well?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes, it's used as a fallback if the swift_clearSensitive
runtime function is not available on a deployment target.
Neat idea, by the way; this is a really nice feature for a language to have. |
@swift-ci test |
@swift-ci test |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
The attribute declares that a struct contains "sensitive" data. It enforces that the contents of such a struct value is zeroed out at the end of its lifetime. In other words: the content of such a value is not observable in memory after the value's lifetime. Also add an experimental feature `Sensitive` with which the attribute can be enabled.
…C structs as `@sensitive` attributes
Call `swift_clearSensitive` after destroying or taking "sensitive" struct types. Also, support calling C-functions with "sensitive" parameters or return values. In SIL, sensitive types are address-only and so are sensitive parameters/return values. Though, (small) sensitive C-structs are passed directly to/from C-functions. We need re-abstract such parameter and return values for C-functions.
@swift-ci smoke test |
The attribute declares that a struct contains "sensitive" data.
It enforces that the contents of such a struct value is zeroed out at the end of its lifetime.
In other words: the content of such a value is not observable in memory after the value's lifetime.
Also, import
__attribute__((swift_attr("sensitive")))
on C structs as@sensitive
attributes.The attribute is mainly implemented in IRGen: IRGen emits a
swift_clearSensitive
runtime call after destroying or taking "sensitive" struct types.Also, IRGen supports calling C-functions with "sensitive" parameters or return values. In SIL, sensitive types are address-only and so are sensitive parameters/return values. Though, (small) sensitive C-structs are passed directly to/from C-functions. We need re-abstract such parameter and return values for C-functions.