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: Handle dyn with no principal #123003

Merged
merged 1 commit into from
Mar 25, 2024
Merged

CFI: Handle dyn with no principal #123003

merged 1 commit into from
Mar 25, 2024

Conversation

maurer
Copy link
Contributor

@maurer maurer commented Mar 24, 2024

In user-facing Rust, dyn always has at least one predicate following it. Unfortunately, because we filter out marker traits from receivers at callsites and dyn Sync is, for example, legal, this results in us having dyn types with no predicates on occasion in our alias set encoding. This patch handles cases where there are no predicates in a dyn type which are relevant to its alias set.

Fixes #122998

r? workingjubilee

@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 24, 2024
@rustbot
Copy link
Collaborator

rustbot commented Mar 24, 2024

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

@@ -290,7 +290,7 @@ impl<'tcx> ty::List<ty::PolyExistentialPredicate<'tcx>> {
/// have a "trivial" vtable consisting of just the size, alignment,
/// and destructor.
pub fn principal(&self) -> Option<ty::Binder<'tcx, ExistentialTraitRef<'tcx>>> {
self[0]
self.get(0)?
Copy link
Member

Choose a reason for hiding this comment

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

I don't like changing this invariant in rustc_middle just because CFI makes bad types 😞

Copy link
Member

Choose a reason for hiding this comment

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

No other place in the compiler expects or constructs dyn types with no predicates.

Copy link
Contributor Author

@maurer maurer Mar 24, 2024

Choose a reason for hiding this comment

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

Since later on in the type encoding process, this type will be examined under normalization, I can't just guard against calling principal in the calling code. Given your comment, that probably means I need to avoid constructing 0-predicate dyn

Do you have suggestions for predicates or representations that would make sense here? The case in question is that I have a dyn Send and dyn Sync - they share a vtable. This vtable has one method, drop_in_place. For purposes of checking the alias set, do you have opinions on what it should be encoded as? The only thing I will know about this object at the method site is that it is a dyn with no principal.

Three possible encodings that come to mind:

  • dyn Drop - I don't like this because these types may not implement Drop, and methods which require fn drop shouldn't go here, but it is descriptive.
  • dyn Sized - I'm considering this specifically because you can't normally have a dyn Sized object, and so it can't accidentally match anything else.
  • Contract the entire receiver to *mut () - this technically discards the alias set restriction that someone made a dyn out of this type at some point in the program, but should otherwise be fine. Note - switching from *dyn to *` is safe in this particular situation because this is only being used to encode vtable calls, which are already using thin-dyn pointers.

I'm currently adjusting my code to use the *mut () approach, but figured I'd lay out my thoughts and see if you have a different opinion.

Copy link
Member

Choose a reason for hiding this comment

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

You could perhaps use dyn Destruct, which every type currently implements (and approximately matches the fact that all we know is that it has a drop_in_place)?

*mut () also works I guess.

@@ -760,7 +760,11 @@ fn transform_predicates<'tcx>(
ty::ExistentialPredicate::AutoTrait(..) => Some(predicate),
})
.collect();
tcx.mk_poly_existential_predicates(&predicates)
if predicates.len() == 0 {
Copy link
Member

Choose a reason for hiding this comment

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

Above comment is in conflict w/ this hack, for example.

Copy link
Member

Choose a reason for hiding this comment

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

Map it to dyn Drop or something if you need a dummy principal trait to put in there.

@compiler-errors
Copy link
Member

I'd like to review this and the other CFI PR you put up since they're actually kind of related to the type system

r? compiler-errors

@workingjubilee
Copy link
Member

I indeed should not be the primary reviewer on anything that is basically just rustc_middle action. I specifically gazed into the ABIss.

In user-facing Rust, `dyn` always has at least one predicate following
it. Unfortunately, because we filter out marker traits from receivers at
callsites and `dyn Sync` is, for example, legal, this results in us
having `dyn` types with no predicates on occasion in our alias set
encoding. This patch handles cases where there are no predicates in a
`dyn` type which are relevant to its alias set.

Fixes rust-lang#122998
Copy link
Member

@compiler-errors compiler-errors left a comment

Choose a reason for hiding this comment

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

This is fine for now!

@compiler-errors
Copy link
Member

@bors r+ rollup

@bors
Copy link
Contributor

bors commented Mar 24, 2024

📌 Commit ea45185 has been approved by compiler-errors

It is now in the queue for this repository.

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Mar 24, 2024
matthiaskrgr added a commit to matthiaskrgr/rust that referenced this pull request Mar 24, 2024
CFI: Handle dyn with no principal

In user-facing Rust, `dyn` always has at least one predicate following it. Unfortunately, because we filter out marker traits from receivers at callsites and `dyn Sync` is, for example, legal, this results in us having `dyn` types with no predicates on occasion in our alias set encoding. This patch handles cases where there are no predicates in a `dyn` type which are relevant to its alias set.

Fixes rust-lang#122998

r? workingjubilee
bors added a commit to rust-lang-ci/rust that referenced this pull request Mar 24, 2024
…iaskrgr

Rollup of 7 pull requests

Successful merges:

 - rust-lang#120557 (Add rust-lldb pretty printing for Path and PathBuf)
 - rust-lang#121051 (Introduce infrastructure for generating target docs)
 - rust-lang#122892 (fix(bootstrap/dist): use versioned dirs when vendoring)
 - rust-lang#122896 (Update stdarch submodule)
 - rust-lang#122923 (In `pretty_print_type()`, print `async fn` futures' paths instead of spans.)
 - rust-lang#122970 (Use `chunk_by` when building `ReverseSccGraph`)
 - rust-lang#123003 (CFI: Handle dyn with no principal)

r? `@ghost`
`@rustbot` modify labels: rollup
bors added a commit to rust-lang-ci/rust that referenced this pull request Mar 25, 2024
…iaskrgr

Rollup of 7 pull requests

Successful merges:

 - rust-lang#120557 (Add rust-lldb pretty printing for Path and PathBuf)
 - rust-lang#121051 (Introduce infrastructure for generating target docs)
 - rust-lang#122892 (fix(bootstrap/dist): use versioned dirs when vendoring)
 - rust-lang#122896 (Update stdarch submodule)
 - rust-lang#122923 (In `pretty_print_type()`, print `async fn` futures' paths instead of spans.)
 - rust-lang#122970 (Use `chunk_by` when building `ReverseSccGraph`)
 - rust-lang#123003 (CFI: Handle dyn with no principal)

r? `@ghost`
`@rustbot` modify labels: rollup
matthiaskrgr added a commit to matthiaskrgr/rust that referenced this pull request Mar 25, 2024
CFI: Handle dyn with no principal

In user-facing Rust, `dyn` always has at least one predicate following it. Unfortunately, because we filter out marker traits from receivers at callsites and `dyn Sync` is, for example, legal, this results in us having `dyn` types with no predicates on occasion in our alias set encoding. This patch handles cases where there are no predicates in a `dyn` type which are relevant to its alias set.

Fixes rust-lang#122998

r? workingjubilee
bors added a commit to rust-lang-ci/rust that referenced this pull request Mar 25, 2024
…iaskrgr

Rollup of 8 pull requests

Successful merges:

 - rust-lang#122802 (Provide structured suggestion for unconstrained generic constant)
 - rust-lang#122858 (Tweak `parse_dot_suffix_expr`)
 - rust-lang#122923 (In `pretty_print_type()`, print `async fn` futures' paths instead of spans.)
 - rust-lang#122990 (Clarify transmute example)
 - rust-lang#122995 (Clean up unnecessary headers/flags in coverage mir-opt tests)
 - rust-lang#123003 (CFI: Handle dyn with no principal)
 - rust-lang#123005 (CFI: Support complex receivers)
 - rust-lang#123020 (Temporarily remove nnethercote from the review rotation.)

r? `@ghost`
`@rustbot` modify labels: rollup
matthiaskrgr added a commit to matthiaskrgr/rust that referenced this pull request Mar 25, 2024
CFI: Handle dyn with no principal

In user-facing Rust, `dyn` always has at least one predicate following it. Unfortunately, because we filter out marker traits from receivers at callsites and `dyn Sync` is, for example, legal, this results in us having `dyn` types with no predicates on occasion in our alias set encoding. This patch handles cases where there are no predicates in a `dyn` type which are relevant to its alias set.

Fixes rust-lang#122998

r? workingjubilee
bors added a commit to rust-lang-ci/rust that referenced this pull request Mar 25, 2024
…iaskrgr

Rollup of 8 pull requests

Successful merges:

 - rust-lang#120557 (Add rust-lldb pretty printing for Path and PathBuf)
 - rust-lang#122802 (Provide structured suggestion for unconstrained generic constant)
 - rust-lang#122858 (Tweak `parse_dot_suffix_expr`)
 - rust-lang#122990 (Clarify transmute example)
 - rust-lang#122995 (Clean up unnecessary headers/flags in coverage mir-opt tests)
 - rust-lang#123003 (CFI: Handle dyn with no principal)
 - rust-lang#123005 (CFI: Support complex receivers)
 - rust-lang#123020 (Temporarily remove nnethercote from the review rotation.)

r? `@ghost`
`@rustbot` modify labels: rollup
bors added a commit to rust-lang-ci/rust that referenced this pull request Mar 25, 2024
…iaskrgr

Rollup of 8 pull requests

Successful merges:

 - rust-lang#120557 (Add rust-lldb pretty printing for Path and PathBuf)
 - rust-lang#122802 (Provide structured suggestion for unconstrained generic constant)
 - rust-lang#122858 (Tweak `parse_dot_suffix_expr`)
 - rust-lang#122990 (Clarify transmute example)
 - rust-lang#122995 (Clean up unnecessary headers/flags in coverage mir-opt tests)
 - rust-lang#123003 (CFI: Handle dyn with no principal)
 - rust-lang#123005 (CFI: Support complex receivers)
 - rust-lang#123020 (Temporarily remove nnethercote from the review rotation.)

r? `@ghost`
`@rustbot` modify labels: rollup
bors added a commit to rust-lang-ci/rust that referenced this pull request Mar 25, 2024
…iaskrgr

Rollup of 7 pull requests

Successful merges:

 - rust-lang#122858 (Tweak `parse_dot_suffix_expr`)
 - rust-lang#122982 (Add more comments to the bootstrap code that handles `tests/coverage`)
 - rust-lang#122990 (Clarify transmute example)
 - rust-lang#122995 (Clean up unnecessary headers/flags in coverage mir-opt tests)
 - rust-lang#123003 (CFI: Handle dyn with no principal)
 - rust-lang#123005 (CFI: Support complex receivers)
 - rust-lang#123020 (Temporarily remove nnethercote from the review rotation.)

r? `@ghost`
`@rustbot` modify labels: rollup
@bors bors merged commit 84ec66e into rust-lang:master Mar 25, 2024
11 checks passed
@rustbot rustbot added this to the 1.79.0 milestone Mar 25, 2024
rust-timer added a commit to rust-lang-ci/rust that referenced this pull request Mar 25, 2024
Rollup merge of rust-lang#123003 - maurer:dyn-empty, r=compiler-errors

CFI: Handle dyn with no principal

In user-facing Rust, `dyn` always has at least one predicate following it. Unfortunately, because we filter out marker traits from receivers at callsites and `dyn Sync` is, for example, legal, this results in us having `dyn` types with no predicates on occasion in our alias set encoding. This patch handles cases where there are no predicates in a `dyn` type which are relevant to its alias set.

Fixes rust-lang#122998

r? workingjubilee
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-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. 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.

ICE: cfi: index out of bounds: the len is 0 but the index is 0 dyn star
5 participants