Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # 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.
# for free to join this conversation on GitHub. Already have an account? # 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