Skip to content

Investigate proper Rust CFI implementation #4876

Description

@CohenArthur

This will be needed in order to properly support Control Flow Integrity. I reached out to @Darksonn to discuss CFI use in the Rust parts of the Linux kernel especially, and she gave me some really useful information for CFI implementation details that I'm pasting here verbatim (with her approval):

A few implementation tips:

In some scenarios you will need to create a "trampoline" to give a
function a different signature than its "native" signature. For
example, given:

trait Foo {
    fn foo(&self);
}

impl Foo for String {
    fn foo(&self) { println!("{}", self); }
}

Then String::foo will give you an fn(&String), and the hash stored for
this function pointer needs to be the hash for that signature. This
means that it cannot be the same function pointer as the one stored in
the Foo vtable for String, as that function pointer is invoked with
dynamic dispatch by callers that expect a signature of "pointer to
Foo" rather than "pointer to String".

Similarly, a Rust vtable also contains a function pointer to the
destructor, and the same problem applies here. But this one has one
difference as the same destructor can be in many vtables for different
traits.

Rust approached this by letting the "native" signature of
String::foo() be a pointer to "Foo", and if you create an fn(&String)
to the same function, then rustc generates a trammpoline function that
has the other signature and calls the original function. This ensures
that trampolines are not needed for the common case (the fp in the
vtable). The trampoline is just a function that will immediately jump
to the true implementation.

For destructors the reverse convention is chosen. This means that
trait vtables contain a trampoline to the destructor.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    codegenrust-for-linuxIssue related to the compilation of the Linux kernel and its crates

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions