Skip to content
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: SIGILL reached via trait objects #106547

Closed
maurer opened this issue Jan 6, 2023 · 3 comments · Fixed by #111375
Closed

CFI: SIGILL reached via trait objects #106547

maurer opened this issue Jan 6, 2023 · 3 comments · Fixed by #111375
Assignees
Labels
C-bug Category: This is a bug. PG-exploit-mitigations Project group: Exploit mitigations

Comments

@maurer
Copy link
Contributor

maurer commented Jan 6, 2023

I tried this code:

struct T;
trait TT {
    fn foo(&self);
}

impl TT for T {
    fn foo(&self) {
        println!("foo");
    }
}

fn main() {
    let x = T;
    let y = &x as &dyn TT;
    y.foo();
}

I expected to see this happen: "foo" should be printed and the program should exit, as in

mmaurer@curtana:~/printer$ cargo run
   Compiling printer v0.1.0 (/usr/local/google/home/mmaurer/printer)
    Finished dev [unoptimized + debuginfo] target(s) in 0.29s
     Running `target/debug/printer`
foo
mmaurer@curtana:~/printer$

Instead, this happened: "Illegal instruction" is printed as the program has received a SIGILL

mmaurer@curtana:~/printer$ RUSTFLAGS="-Zsanitizer=cfi -C lto -Cembed-bitcode=yes" cargo run
   Compiling printer v0.1.0 (/usr/local/google/home/mmaurer/printer)
    Finished dev [unoptimized + debuginfo] target(s) in 2.51s
     Running `target/debug/printer`
Illegal instruction
mmaurer@curtana:~/printer$ echo $?
132
mmaurer@curtana:~/printer$ 

Meta

rustc --version --verbose:

rustc 1.68.0-nightly (388538fc9 2023-01-05)
binary: rustc
commit-hash: 388538fc963e07a94e3fc3ac8948627fd2d28d29
commit-date: 2023-01-05
host: x86_64-unknown-linux-gnu
release: 1.68.0-nightly
LLVM version: 15.0.6
@maurer maurer added the C-bug Category: This is a bug. label Jan 6, 2023
@maurer
Copy link
Contributor Author

maurer commented Jan 6, 2023

cc @rcvalle

@maurer
Copy link
Contributor Author

maurer commented Jan 6, 2023

@rustbot claim

Ran into this while trying to enable KCFI for Linux, and found that the same bug exists in a much more simple environment with the arguably-more-stable CFI support. I'll be debugging this later today or early next week, but wanted to post this since I know the problem exists.

@maurer
Copy link
Contributor Author

maurer commented Jan 11, 2023

The core of the problem here is that the type data for T::Foo correctly wants to receive a &T, not a &dyn TT. The thunk generated at the &dyn TT based call checks T::Foo expecting &dyn TT to be legal.

clang typechecks their vtables rather than their functions for this, which I think makes sense - it doesn't require us to thunk the function, and doesn't end up with a looser-than-true piece of metadata on each call.

I'll take a crack at that next.

@rcvalle rcvalle added the PG-exploit-mitigations Project group: Exploit mitigations label Apr 18, 2023
compiler-errors added a commit to compiler-errors/rust that referenced this issue May 12, 2023
CFI: Fix SIGILL reached via trait objects

Fix rust-lang#106547 by transforming the concrete self into a reference to a trait object before emitting type metadata identifiers for trait methods.
@bors bors closed this as completed in 7c7b22e May 12, 2023
rcvalle added a commit to rcvalle/rust that referenced this issue May 17, 2023
Fixes rust-lang#111510 and complements rust-lang#106547 by adding support for encoding
type parameters and also by transforming trait objects' traits into
their identities before emitting type checks.
bors added a commit to rust-lang-ci/rust that referenced this issue May 21, 2023
CFI: Fix encode_ty: unexpected Param(B/#1)

Fixes rust-lang#111510 and complements rust-lang#106547 by adding support for encoding type parameters and also by transforming trait objects' traits into their identities before emitting type checks.
rcvalle added a commit to rcvalle/rust that referenced this issue May 23, 2023
Fixes rust-lang#111515 and complements rust-lang#106547 by adding support for encoding
early bound regions and also excluding projections when transforming
trait objects' traits into their identities before emitting type checks.
matthiaskrgr added a commit to matthiaskrgr/rust that referenced this issue May 23, 2023
CFI: Fix encode_region: unexpected ReEarlyBound(0, 'a)

Fixes rust-lang#111515 and complements rust-lang#106547 by adding support for encoding early bound regions and also excluding projections when transforming trait objects' traits into their identities before emitting type checks.
rcvalle added a commit to rcvalle/rust that referenced this issue Jul 17, 2023
Fixes rust-lang#100778 and rust-lang#113366, and complements rust-lang#106547 by adding support for
encoding const parameters.
bors added a commit to rust-lang-ci/rust that referenced this issue Jul 27, 2023
…ler-errors

CFI: Fix ICE: encode_const: unexpected type [usize

Fixes rust-lang#100778 and rust-lang#113366, and complements rust-lang#106547 by adding support for encoding const parameters.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-bug Category: This is a bug. PG-exploit-mitigations Project group: Exploit mitigations
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants