-
Notifications
You must be signed in to change notification settings - Fork 12.7k
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
cfi: Store type erasure witness for Argument #115954
base: master
Are you sure you want to change the base?
Conversation
r? @m-ou-se (rustbot has picked a reviewer for you, use r? to override) |
☔ The latest upstream changes (presumably #123819) made this pull request unmergeable. Please resolve the merge conflicts. |
this is no longer blocked as the issue it was blocked on is resolved. marking this as on-author so that @maurer can resolve the conflicts and we can push this forward |
CFI/KCFI work by enforcing that indirect function calls are always called at the type they were defined at. The type erasure in Argument works by casting the reference to the value to be formatted to an Opaque and also casting the function to format it to take an Opaque reference. While this is *ABI* safe, which is why we get away with it normally, it does transform the type that the function is called at. This means that at the call-site, CFI expects the type of the function to be `fn(&Opaque, ` even though it is really `fn(&T, ` for some particular `T`. This patch avoids this by adding `cast_stub`, a witness to the type erasure that will cast the `&Opaque` and `fn(&Opaque` back to their original types before invoking the function. This change is guarded by the enablement of CFI as it will require an additional pointer-sized value per `Argument`, and an additional jump during formatting, and we'd prefer not to pay that if we don't need the types to be correct at the indirect call invocation.
I've resolved the conflict, but in manual testing, found that while this makes Testing summary of the situation after this commit - Program:
KCFI, with the patch, failing
CFI, before the patch, failing
CFI, after the patch, succeeding
|
FWIW I am not very happy about this. If what Changing what the standard library does under EDIT: I opened an issue for the wider discussion here: #128728 |
This is a WIP that won't work until @rcvalle has fixed address-taken trait functions #115953 but I understand he has a fix for that on the way.
Once that's out of the way, this addresses #115199 point 2.
CFI/KCFI work by enforcing that indirect function calls are always called at the type they were defined at. The type erasure in Argument works by casting the reference to the value to be formatted to an Opaque and also casting the function to format it to take an Opaque reference.
While this is ABI safe, which is why we get away with it normally, it does transform the type that the function is called at. This means that at the call-site, CFI expects the type of the function to be
fn(&Opaque,
even though it is reallyfn(&T,
for some particularT
.This patch avoids this by adding
cast_stub
, a witness to the type erasure that will cast the&Opaque
andfn(&Opaque
back to their original types before invoking the function.This change is guarded by the enablement of CFI as it will require an additional pointer-sized value per
Argument
, and an additional jump during formatting, and we'd prefer not to pay that if we don't need the types to be correct at the indirect call invocation.