- Notifications
You must be signed in to change notification settings - Fork 13.9k
cmse: lint on unions crossing the secure boundary #147697
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
base: master
Are you sure you want to change the base?
cmse: lint on unions crossing the secure boundary #147697
Conversation
This comment has been minimized.
This comment has been minimized.
a344d30
to 514010e
Compare This comment has been minimized.
This comment has been minimized.
514010e
to 9d276b5
Compare This comment has been minimized.
This comment has been minimized.
9d276b5
to 4a269f5
Compare This comment has been minimized.
This comment has been minimized.
4a269f5
to 0b424f6
Compare r? @davidtwco This seems useful just for parity with clang. The code is built to be extended to cover more cases of types possibly containing uninitialized memory, but by the looks of things there isn't currently a straightforward way to detect such types (cc #t-compiler/help > check whether a type can be (partially) uninitialized) |
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.
Implementation LGTM, two nits, but will need t-lang approval for a new lint
#[no_mangle] | ||
#[allow(improper_ctypes_definitions)] | ||
pub extern "cmse-nonsecure-entry" fn f5(_: [u32; 5]) {} //~ ERROR [E0798] | ||
// |
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.
// |
nit
use minicore::*; | ||
| ||
#[repr(Rust)] | ||
pub union ReprRustUnionU64 { |
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.
Can you add cases where the unions are contained within other types to these tests?
When a union passes from secure to non-secure (so, passed as an argument to an nonsecure call, or returned by a nonsecure entry), warn that there may be secure information lingering in the unused or uninitialized parts of a union value. https://godbolt.org/z/vq9xnrnEs
0b424f6
to 4586300
Compare 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.
The lint will only fire when the cmse ABIs are enabled, but I suppose the name does sort of "leak".
the OP here provides some context. The bigger picture is in this draft RFC that I plan to formally submit soon.
warning: passing a union across the security boundary may leak information | ||
--> $DIR/return-uninitialized.rs:46:5 | ||
| | ||
LL | / match 0 { | ||
LL | | | ||
LL | | 0 => Wrapper(ReprRustUnionU64 { _unused: 1 }), | ||
LL | | _ => Wrapper(ReprRustUnionU64 { _unused: 2 }), | ||
LL | | } | ||
| |_____^ | ||
| |
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.
would it make sense to warn in the individual arms of the match
instead? I think as a user that would be better in this simple case, though I don't know that we can make that robust (e.g. thinking about labeled blocks).
tracking issue: #81391
tracking issue: #75835
When a union passes from secure to non-secure (so, passed as an argument to a non-secure call, or returned by a non-secure entry), warn that there may be secure information lingering in the unused or uninitialized parts of a union value.
This lint matches the behavior of clang (see https://godbolt.org/z/vq9xnrnEs). Like clang we warn at the use site, so that individual uses could be annotated with
#[allow(cmse_uninitialized_leak)]
.Ideally we'd warn on any type that may have uninitialized parts, but I haven't figured out a good way to do that yet.
It is still unclear whether a union value where all fields are equally large and allow the same bit patterns can be considered initialized (see rust-lang/unsafe-code-guidelines#438), so for now we just warn on any
union
.r? @ghost