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: Fix fn items, closures, and Fn trait objects #123082

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

rcvalle
Copy link
Member

@rcvalle rcvalle commented Mar 26, 2024

Fix casting between function items, closures, and Fn trait objects by transforming function items, closures, and Fn trait objects into function pointers for encoding.

This was split off from #116404.

cc @compiler-errors @workingjubilee

@rustbot
Copy link
Collaborator

rustbot commented Mar 26, 2024

r? @lcnr

rustbot has assigned @lcnr.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

@rustbot rustbot added PG-exploit-mitigations Project group: Exploit mitigations S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Mar 26, 2024
@rustbot
Copy link
Collaborator

rustbot commented Mar 26, 2024

Some changes occurred in tests/codegen/sanitizer

cc @rust-lang/project-exploit-mitigations, @rcvalle

Some changes occurred in tests/ui/sanitizer

cc @rust-lang/project-exploit-mitigations, @rcvalle

Some changes occurred in compiler/rustc_symbol_mangling/src/typeid

cc @rust-lang/project-exploit-mitigations, @rcvalle

@rcvalle
Copy link
Member Author

rcvalle commented Mar 26, 2024

r? @compiler-errors

@rustbot rustbot assigned compiler-errors and unassigned lcnr Mar 26, 2024
Copy link
Contributor

@maurer maurer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review not yet complete, heading out to something else but wanted to leave what comments I had so far.

My biggest concern is how deeply this needs to adjust our type encoding to deal with closures and Fn traits, and the number of epicycles it seems to add. I'll extend the review later tonight or tomorrow morning.

tcx.lifetimes.re_erased,
*kind,
);
if is_fn_trait(tcx, predicates) || is_fn_subtrait(tcx, predicates) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This would only be possible with #[feature(fn_traits)], and doesn't seem likely in user code, but doesn't this mean that something like this:

trait CountedCallable: Fn(i32) {
  fn times_called(&self) -> usize;
}
struct Foo;
impl Fn<(i32)> for Foo { /* .. */ }
impl CountedCallable for Foo { /* .. */ } 

then Foo::times_called would have an encoded alias set of fn(fn(i32)) -> usize? Is that intended?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, but your alternative at #123106, would require attaching either as the main or secondary type id fn(&dyn Fn(i32)) -> usize as well, right?

return Some(args[0].expect_ty().tuple_fields());
}
if is_fn_subtrait(tcx, predicates) {
return Some(List::empty());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't seem right. Two problems I see here:

  1. Does this mean that you're encoding the args as empty regardless of what the trait implements?
  2. A trait can have multiple fn traits as supertraits, e.g. trait Foo: Fn() + Fn(i32) -> u8 {}. It's weird, but since you're implementing this it seems worth discussing.

These same questions stand for fn_trait_output.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, it coalesces it under the first Fn supertrait found. How does #123106 handle it?

@rcvalle rcvalle force-pushed the rust-cfi-fix-fn-items-closures-fn-trait-objects branch from 11b6387 to faba20b Compare March 27, 2024 02:42
@rustbot
Copy link
Collaborator

rustbot commented Mar 27, 2024

Some changes occurred in tests/codegen/sanitizer

cc @rust-lang/project-exploit-mitigations, @rcvalle

Some changes occurred in compiler/rustc_symbol_mangling/src/typeid

cc @rust-lang/project-exploit-mitigations, @rcvalle

Some changes occurred in tests/ui/sanitizer

cc @rust-lang/project-exploit-mitigations, @rcvalle

@rcvalle rcvalle force-pushed the rust-cfi-fix-fn-items-closures-fn-trait-objects branch from faba20b to 7c14164 Compare March 27, 2024 03:24
Fix casting between function items, closures, and Fn trait objects by
transforming function items, closures, and Fn trait objects into
function pointers for encoding.
@rcvalle rcvalle force-pushed the rust-cfi-fix-fn-items-closures-fn-trait-objects branch from 7c14164 to 70ac00e Compare March 27, 2024 03:27
@rcvalle
Copy link
Member Author

rcvalle commented Mar 27, 2024

We're moving forward with #123106, which is a variant of this (that transforms closures into dynamic Fn traits but isolating it to the Fn call methods only). See my comment on #123106 (comment).

@bors
Copy link
Contributor

bors commented Mar 27, 2024

☔ The latest upstream changes (presumably #123128) made this pull request unmergeable. Please resolve the merge conflicts.

rcvalle added a commit to rcvalle/rust that referenced this pull request Mar 29, 2024
Since we're now using an approach which is a variant of rust-lang#123082 (that
transforms closures into dynamic Fn traits but isolating it to the Fn
call methods only) instead of rust-lang#121962 or rust-lang#122573, skipping non-passed
arguments shouldn't be necessary KCFI anymore and we can claim back the
reduced granularity.

This reverts commit f2f0d25.
rcvalle added a commit to rcvalle/rust that referenced this pull request Mar 29, 2024
Since we're now using an approach which is a variant of rust-lang#123082 (that
transforms closures into dynamic Fn traits but isolating it to the Fn
call methods only) instead of rust-lang#121962 or rust-lang#122573, skipping non-passed
arguments shouldn't be necessary for KCFI anymore and we can claim back
the reduced granularity.

This reverts commit f2f0d25.
maurer pushed a commit to maurer/rust that referenced this pull request Apr 4, 2024
Since we're now using an approach which is a variant of rust-lang#123082 (that
transforms closures into dynamic Fn traits but isolating it to the Fn
call methods only) instead of rust-lang#121962 or rust-lang#122573, skipping non-passed
arguments shouldn't be necessary for KCFI anymore and we can claim back
the reduced granularity.

This reverts commit f2f0d25.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
PG-exploit-mitigations Project group: Exploit mitigations S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants