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

[WIP] Impl a more strict transmute check #51294

Closed
wants to merge 4 commits into from

Conversation

nagisa
Copy link
Member

@nagisa nagisa commented Jun 2, 2018

Requesting a crater run to see the potential impact of forbidding transmutes to and from types with unspecified layouts.

@rust-highfive
Copy link
Collaborator

r? @michaelwoerister

(rust_highfive has picked a reviewer for you, use r? to override)

@rust-highfive rust-highfive added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Jun 2, 2018
@nagisa
Copy link
Member Author

nagisa commented Jun 2, 2018

Note: do not review the implementation approach too strictly ­– it is a quick and dirty implementation purely to check for how wide an impact on ecosystem would such a change have.

@rust-highfive
Copy link
Collaborator

The job x86_64-gnu-llvm-3.9 of your PR failed on Travis (raw log). Through arcane magic we have determined that the following fragments from the build log may contain information about the problem.

Click to expand the log.
[00:08:01] For more information about this error, try `rustc --explain E0308`.
[00:08:01] error: Could not compile `rustc`.
[00:08:01] 
[00:08:01] Caused by:
[00:08:01]   process didn't exit successfully: `/checkout/obj/build/bootstrap/debug/rustc --crate-name rustc librustc/lib.rs --color always --error-format json --crate-type dylib --emit=dep-info,link -C prefer-dynamic -C opt-level=2 -C metadata=622bce453bbffbd5 -C extra-filename=-622bce453bbffbd5 --out-dir /checkout/obj/build/x86_64-unknown-linux-gnu/stage0-rustc/x86_64-unknown-linux-gnu/release/deps --target x86_64-unknown-linux-gnu -L dependency=/checkout/obj/build/x86_64-unknown-linux-gnu/stage0-rustc/x86_64-unknown-linux-gnu/release/deps -L dependency=/checkout/obj/build/x86_64-unknown-linux-gnu/stage0-rustc/release/deps --extern rustc_apfloat=/checkout/obj/build/x86_64-unknown-linux-gnu/stage0-rustc/x86_64-unknown-linux-gnu/release/deps/librustc_apfloat-642a7efe79e24835.rlib --extern byteorder=/checkout/obj/build/x86_64-unknown-linux-gnu/stage0-rustc/x86_64-unknown-linux-gnu/release/deps/libbyteorder-78ebc049d4f53f46.rlib --extern backtrace=/checkout/obj/build/x86_64-unknown-linux-gnu/stage0-rustc/x86_64-unknown-linux-gnu/release/deps/libbacktrace-f3a2fb1d767a0bf7.rlib --extern bitflags=/checkout/obj/build/x86_64-unknown-linux-gnu/stage0-rustc/x86_64-unknown-linux-gnu/release/deps/libbitflags-99b4534960f92449.rlib --extern log=/checkout/obj/build/x86_64-unknown-linux-gnu/stage0-rustc/x86_64-unknown-linux-gnu/release/deps/liblog-5073f1296cd24b67.rlib --extern syntax=/checkout/obj/build/x86_64-unknown-linux-gnu/stage0-rustc/x86_64-unknown-linux-gnu/release/deps/libsyntax-4c5434c80172b18c.so --extern proc_macro=/checkout/obj/build/x86_64-unknown-linux-gnu/stage0-rustc/x86_64-unknown-linux-gnu/release/deps/libproc_macro-f53f15d4555417c6.so --extern polonius_engine=/checkout/obj/build/x86_64-unknown-linux-gnu/stage0-rustc/x86_64-unknown-linux-gnu/release/deps/libpolonius_engine-fea5947f694181d1.rlib --extern arena=/checkout/obj/build/x86_64-unknown-linux-gnu/stage0-rustc/x86_64-unknown-linux-gnu/release/deps/libarena-9f4c7501a8934cc5.so --extern rustc_target=/checkout/obj/build/x86_64-unknown-linux-gnu/stage0-rustc/x86_64-unknown-linux-gnu/release/deps/librustc_target-58741ed9de9aae4f.so --extern rustc_data_structures=/checkout/obj/build/x86_64-unknown-linux-gnu/stage0-rustc/x86_64-unknown-linux-gnu/release/deps/librustc_data_structures-05d59ed98ebd8949.so --extern chalk_engine=/checkout/obj/build/x86_64-unknown-linux-gnu/stage0-rustc/x86_64-unknown-linux-gnu/release/deps/libchalk_engine-dc5a2a01279da0f2.rlib --extern jobserver=/checkout/obj/build/x86_64-unknown-linux-gnu/stage0-rustc/x86_64-unknown-linux-gnu/release/deps/libjobserver-e8a1df2f3ad631bc.rlib --extern graphviz=/checkout/obj/build/x86_64-unknown-linux-gnu/stage0-rustc/x86_64-unknown-linux-gnu/release/deps/libgraphviz-be994de8b3050feb.so --extern serialize=/checkout/obj/build/x86_64-unknown-linux-gnu/stage0-rustc/x86_64-unknown-linux-gnu/release/deps/libserialize-5d0a8a65bb9fe29f.so --extern serialize=/checkout/obj/build/x86_64-unknown-linux-gnu/stage0-rustc/x86_64-unknown-linux-gnu/release/deps/ bootstrap/compile.rs:1091:9
[00:08:01] travis_fold:end:stage0-rustc

[00:08:01] travis_time:end:stage0-rustc:start=1527933190270699318,finish=1527933382861014433,duration=192590315115


[00:08:01] failed to run: /checkout/obj/build/bootstrap/debug/bootstrap build
[00:08:01] Build completed unsuccessfully in 0:03:25
[00:08:01] make: *** [all] Error 1
[00:08:01] Makefile:28: recipe for target 'all' failed
315008 ./src/llvm
249872 ./obj/build/x86_64-unknown-linux-gnu/stage0/lib/rustlib/x86_64-unknown-linux-gnu/lib
241184 ./src/llvm-emscripten
210196 ./src/llvm/test
---
146444 ./.git/modules
146440 ./.git/modules/src
137732 ./obj/build/bootstrap/debug/incremental
123180 ./obj/build/bootstrap/debug/incremental/bootstrap-1r3bppl29tbrj
123176 ./obj/build/bootstrap/debug/incremental/bootstrap-1r3bppl29tbrj/s-f1luqjpdec-wnllba-2rxy29zuufd4c
92436 ./obj/build/x86_64-unknown-linux-gnu/stage0-rustc
89804 ./src/llvm/test/CodeGen
71572 ./.git/modules/src/tools
70500 ./obj/build/x86_64-unknown-linux-gnu/native
---
travis_fold:end:after_failure.3
travis_fold:start:after_failure.4
travis_time:start:14f5e734
$ dmesg | grep -i kill
[    3.332454] misc rfkill: hash matches
travis_time:end:14f5e734:start=1527933383433054192,finish=1527933383446434817,duration=13380625
travis_fold:end:after_failure.4

Done. Your build exited with 1.

I'm a bot! I can only do what humans tell me to, so if this was not helpful or you have suggestions for improvements, please ping or otherwise contact @TimNN. (Feature Requests)

None,
// Outright unspecified to be anything in particular
TyClosure(_, _) | TyGenerator(_, _, _) | TyGeneratorWitness(_) => Some(false),
TyFnDef(_, _) => Some(false),
Copy link
Contributor

Choose a reason for hiding this comment

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

Aren't function definitions guaranteed to be zst? (Not that it's useful to transmute them... but still)

Copy link
Member Author

Choose a reason for hiding this comment

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

I don't recall us specifying that at any point (and in fact, I remember us debating whether we should make fndef types be a pointer in the past).

Either way, I’m willing to filter out those cases, if they occur on a crater run, manually.

Copy link
Member

Choose a reason for hiding this comment

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

We had a warning period when we made them ZSTs, see also E0591 in intrinsicck.
I think Some(false) here is decent.

let field_ty = field.ty(tcx, substs);
match field_ty.has_specified_layout(tcx) {
Some(true) => continue,
x => return x,
Copy link
Contributor

Choose a reason for hiding this comment

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

None should probably continue, too, but produce None in the end if no Some(false) was encountered before. Otherwise the field order can silence the lint

@nagisa nagisa force-pushed the transmute-lint branch 3 times, most recently from 7640c81 to 95c58be Compare June 2, 2018 10:53
@pietroalbini pietroalbini added S-waiting-on-crater Status: Waiting on a crater run to be completed. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Jun 2, 2018
@pietroalbini
Copy link
Member

@bors try

@bors
Copy link
Contributor

bors commented Jun 2, 2018

⌛ Trying commit 95c58be with merge 7816e92...

bors added a commit that referenced this pull request Jun 2, 2018
[WIP] Impl a more strict transmute check

Requesting a crater run to see the potential impact of forbidding transmutes to and from types with unspecified layouts.
@bors
Copy link
Contributor

bors commented Jun 2, 2018

☀️ Test successful - status-travis
State: approved= try=True

@pietroalbini
Copy link
Member

build-only crater run started on crater-1.

@nagisa nagisa assigned eddyb and unassigned michaelwoerister Jun 2, 2018
@nagisa
Copy link
Member Author

nagisa commented Jun 5, 2018

@pietroalbini Has the crater run been completed yet?

@pietroalbini
Copy link
Member

@nagisa nope, it's running and it should finish in a few days.

// FIXME: not for fat pointers.
TyRawPtr(_) => Some(true),

// FIXME: Properly handle sizedness check
Copy link
Member

Choose a reason for hiding this comment

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

You can steal the sizedness check from layout code, I think it's pretty short.

match self.sty {
// Not concrete, cannot say anything
TyInfer(_) | TyError | TyParam(_) | TyProjection(_) | TyAnon(_, _) | TyDynamic(_, _) =>
None,
Copy link
Member

Choose a reason for hiding this comment

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

TyDynamic is a dyn Trait (trait object), so it should be treated like TyStr IMO.

@@ -1848,6 +1848,78 @@ impl<'a, 'gcx, 'tcx> TyS<'tcx> {
_ => bug!("cannot convert type `{:?}` to a closure kind", self),
}
}

//
pub fn has_specified_layout(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Option<bool> {
Copy link
Member

Choose a reason for hiding this comment

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

IMO this should go in intrinsicck and preferably try to resolve projections, like layout code does.

@pietroalbini
Copy link
Member

Hi @nagisa (crater requester), @eddyb (PR reviewer)! Crater results are at: http://cargobomb-reports.s3.amazonaws.com/pr-51294/index.html. 'Blacklisted' crates (spurious failures etc) can be found here. If you see any spurious failures not on the list, please make a PR against that file.

(interested observers: Crater is a tool for testing the impact of changes on the crates.io ecosystem. You can find out more at the repo if you're curious)

@pietroalbini pietroalbini added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-crater Status: Waiting on a crater run to be completed. labels Jun 7, 2018

if to.has_specified_layout(self.tcx) == Some(false) {
unspecified_layout("transmutation to a type with an unspecified layout", to);
}
Copy link
Member

Choose a reason for hiding this comment

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

Wait, this is below the "same size" check (see the return on line 80), is it intentional that it will only trigger if there's a size mismatch?

Copy link
Member Author

Choose a reason for hiding this comment

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

Not intentional, I didn’t notice it.

That likely invalidates the crater run.

@scottmcm
Copy link
Member

Only one crate regressed, and it looks unrelated:

thread 'main' panicked at 'called Result::unwrap() on an Err value: Os { code: 30, kind: Other, message: "Read-only file system" }', libcore/result.rs:945:5

@nagisa
Copy link
Member Author

nagisa commented Jun 16, 2018

I’m working on a fixed implementation at the moment (since @eddyb did found a pretty critical flaw in the implementation that may invalidate the crater results).

@bors
Copy link
Contributor

bors commented Jun 23, 2018

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

@stokhos stokhos added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Jun 29, 2018
@stokhos
Copy link

stokhos commented Jun 29, 2018

ping from triage, @nagisa we haven't hear from you for awhile, will you have time to work on this again?

@nagisa
Copy link
Member Author

nagisa commented Jul 3, 2018

@bors try

requesting a crater run. check-only is fine.

@bors
Copy link
Contributor

bors commented Jul 3, 2018

⌛ Trying commit 18d1459 with merge 5298b81bebd26bb9f87d5f99764aab01595b3f69...

@nagisa
Copy link
Member Author

nagisa commented Jul 3, 2018

So far from the compiler codebase following problematic cases were seen:

  • Identity transmutes that only "transmute" the lifetime;
  • Transmutes to/from raw::TraitObject;
  • Transmutes from Box<Trait> to Box<AnotherTrait>;

@pietroalbini pietroalbini added S-waiting-on-crater Status: Waiting on a crater run to be completed. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Jul 3, 2018
@bors
Copy link
Contributor

bors commented Jul 3, 2018

☀️ Test successful - status-travis
State: approved= try=True

@pietroalbini
Copy link
Member

Crater run started on crater-2. It will finish in 2/3 days.

@pietroalbini
Copy link
Member

Hi @nagisa (crater requester), @eddyb (PR reviewer)! Crater results are at: http://cargobomb-reports.s3.amazonaws.com/pr-51294/index.html. 'Blacklisted' crates (spurious failures etc) can be found here. If you see any spurious failures not on the list, please make a PR against that file.

(interested observers: Crater is a tool for testing the impact of changes on the crates.io ecosystem. You can find out more at the repo if you're curious)

@pietroalbini
Copy link
Member

And congrats for breaking almost half of crates.io!

@petrochenkov
Copy link
Contributor

And congrats for breaking almost half of crates.io!

That's why such experiments are better implemented as deny-by-default lints, so only root regressions show up.

@pietroalbini pietroalbini added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-crater Status: Waiting on a crater run to be completed. labels Jul 7, 2018
@nagisa
Copy link
Member Author

nagisa commented Jul 7, 2018

@petrochenkov a good insight. If I happen to make another experiment, I will make sure that deny-by-default lint is used. It will also not hide failures if the crate is not checked due to depending on the failing crate.


I did some very basic (automated) analysis on the log files. Sorted by impact, these are the "unspecified" layout types that are transmuted the most from or to:

  • &[T], &str, &variant_type::VariantTy (from glib, a repr(Rust) newtype over str);
  • Box<T> (for both T: Sized and T: ?Sized; is it specified to be same as a pointer to T?);
  • *mut dyn T, *const dyn T, &mut dyn T, &dyn T;
  • std::sync::Arc<T> (mostly by futures?);
  • std::net::SocketAddrV4, std::net::SocketAddrV6 (crate socket2);
  • Result;
  • utf8_char::Utf8Char (crate encode_unicode);
  • *mut Self (crate unsafe_any);
  • repr(Rust) structs, tuples;
  • Identity transmutes that only transmute the lifetime;
  • Transmutation to change the mutability of reference from immutable to mutable (even if it only occurs in one crate… what?);

@nagisa
Copy link
Member Author

nagisa commented Jul 7, 2018

cc @nikomatsakis you may be interested in analysis above.

@nagisa
Copy link
Member Author

nagisa commented Jul 12, 2018

Closing the PR and moving the summary to the issue.

@nagisa nagisa closed this Jul 12, 2018
tormol added a commit to tormol/encode_unicode that referenced this pull request Aug 8, 2018
This crate (among others) did'nt compile with an experimental [more strict
transmute check](rust-lang/rust#51294)

Hare's the error messages: (from http://cargobomb-reports.s3.amazonaws.com/pr-51294/5298b81bebd26bb9f87d5f99764aab01595b3f69-alt/reg/encode_unicode-0.3.1/log.txt)
Jul 05 13:02:02.884 INFO kablam! error[E0912]: transmutation to a type with an unspecified layout
Jul 05 13:02:02.884 INFO kablam!    --> src/utf8_char.rs:283:16
Jul 05 13:02:02.884 INFO kablam!     |
Jul 05 13:02:02.884 INFO kablam! 283 |             Ok(transmute(unused_zeroed))
Jul 05 13:02:02.884 INFO kablam!     |                ^^^^^^^^^
Jul 05 13:02:02.884 INFO kablam!     |
Jul 05 13:02:02.884 INFO kablam!     = note: utf8_char::Utf8Char has an unspecified layout
Jul 05 13:02:02.884 INFO kablam!
Jul 05 13:02:02.884 INFO kablam! error[E0912]: transmutation from a type with an unspecified layout
Jul 05 13:02:02.884 INFO kablam!   --> src/utf8_iterator.rs:25:41
Jul 05 13:02:02.884 INFO kablam!    |
Jul 05 13:02:02.884 INFO kablam! 25 |         let used = u32::from_le(unsafe{ mem::transmute(uc) });
Jul 05 13:02:02.884 INFO kablam!    |                                         ^^^^^^^^^^^^^^
Jul 05 13:02:02.884 INFO kablam!    |
Jul 05 13:02:02.884 INFO kablam!    = note: utf8_char::Utf8Char has an unspecified layout
Jul 05 13:02:02.884 INFO kablam!
Jul 05 13:02:02.893 INFO kablam! error: aborting due to 2 previous errors
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

10 participants