-
-
Notifications
You must be signed in to change notification settings - Fork 15.5k
fn_cast! macro #140803
Copy link
Copy link
Open
Labels
A-control-flow-integrityArea: Control Flow Integrity (CFI) security mitigationArea: Control Flow Integrity (CFI) security mitigationA-rust-for-linuxRelevant for the Rust-for-Linux projectRelevant for the Rust-for-Linux projectA-sanitizersArea: Sanitizers for correctness and code qualityArea: Sanitizers for correctness and code qualityC-discussionCategory: Discussion or questions that doesn't represent real issues.Category: Discussion or questions that doesn't represent real issues.I-lang-radarItems that are on lang's radar and will need eventual work or consideration.Items that are on lang's radar and will need eventual work or consideration.PG-exploit-mitigationsProject group: Exploit mitigationsProject group: Exploit mitigationsT-langRelevant to the language teamRelevant to the language team
Description
Metadata
Metadata
Assignees
Labels
A-control-flow-integrityArea: Control Flow Integrity (CFI) security mitigationArea: Control Flow Integrity (CFI) security mitigationA-rust-for-linuxRelevant for the Rust-for-Linux projectRelevant for the Rust-for-Linux projectA-sanitizersArea: Sanitizers for correctness and code qualityArea: Sanitizers for correctness and code qualityC-discussionCategory: Discussion or questions that doesn't represent real issues.Category: Discussion or questions that doesn't represent real issues.I-lang-radarItems that are on lang's radar and will need eventual work or consideration.Items that are on lang's radar and will need eventual work or consideration.PG-exploit-mitigationsProject group: Exploit mitigationsProject group: Exploit mitigationsT-langRelevant to the language teamRelevant to the language team
Since Rust 1.76 we document that it's valid to transmute function pointers from one signature to another as long as their signatures are ABI-compatible. However, we have since learned that these rules may be too broad and allow some transmutes that it is undesirable to permit. Specifically, transmutes that change the pointee type or constness of a pointer argument are considered ABI-compatible, but they are rejected by the CFI sanitizer as incompatible. See rust-lang/unsafe-code-guidelines#489 for additional details and #128728 for a concrete issue.
This issue tracks a proposed solution to the above: Introduce a new macro called
fn_cast!that allows you to change the signature of a function pointer. Under most circumstances, this is equivalent to simply transmuting the function pointer, but in some cases it will generate a new "trampoline" function that transmutes all arguments and calls the original function. This allows you to perform such function casts safely without paying the cost of a trampoline when it's not needed.The argument to
fn_cast!()must be an expression that evaluates to a function item or a non-capturing closure. This ensures that the compiler knows which function is being called at monomorphization time.As a sketch, you can implement a simple version of the macro like this:
This implementation should get the point across, but it is incomplete for a few reasons:
fn_cast!should be improved to work with functions of any arity.fn(&T)tofn(*const T)is allowed because&Tand*const Tis treated the same by KCFI. The compiler could detect such cases and emit a transmute instead of a trampoline.By adding this macro, it becomes feasible to make the following breaking change to the spec:
Here, the change is that ABI-compatible calls are considered EB. However, even without the spec change the macro is useful because it would allow for a more efficient implementation of #139632 than what is possible today.
This proposal was originally made as a comment. I'm filing a new issue because T-lang requested that I do so during the RfL meeting 2025-05-07.