-
-
Notifications
You must be signed in to change notification settings - Fork 14.8k
Memory unsafety problem in safe Rust #69225
Copy link
Copy link
Closed
Labels
A-LLVMArea: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues.Area: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues.C-bugCategory: This is a bug.Category: This is a bug.I-unsoundIssue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/SoundnessIssue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/SoundnessP-mediumMedium priorityMedium priorityT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.Relevant to the compiler team, which will review and decide on the PR/issue.regression-from-stable-to-stablePerformance or correctness regression from one stable version to another.Performance or correctness regression from one stable version to another.
Metadata
Metadata
Assignees
Labels
A-LLVMArea: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues.Area: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues.C-bugCategory: This is a bug.Category: This is a bug.I-unsoundIssue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/SoundnessIssue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/SoundnessP-mediumMedium priorityMedium priorityT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.Relevant to the compiler team, which will review and decide on the PR/issue.regression-from-stable-to-stablePerformance or correctness regression from one stable version to another.Performance or correctness regression from one stable version to another.
Type
Fields
Give feedbackNo fields configured for issues without a type.
I have a small program (a simplification of a test function from a larger project) that slices a small array and tries to access an out-of-bounds element of the slice. Running it with
cargo run --releaseusing the stable1.41.0release prints something like this (tested on macOS 10.15 and Ubuntu 19.10):It looks like the resulting slice somehow has length
2**64 - 1, so the bounds checking is omitted, which predictably results in a segfault. On1.39.0and1.40.0the very same program prints what I would expect:The problem goes away if I do any of the following:
do_test(...);calls inmain();for _ in 0..1 {loop;for y in 0..x {loop withfor y in 0..1 {;z.extend(std::iter::repeat(0).take(x));line or replace it withz.extend(std::iter::repeat(0).take(1));;for arr_ref in arr {loop withlet arr_ref = &arr[0];;RUSTFLAGS="-C opt-level=2";RUSTFLAGS="-C codegen-units=1".My best guess is
-C opt-level=3enables a problematic optimization pass in LLVM, which results in miscompilation. This is corroborated by the fact that MIR (--emit mir) and LLVM IR before optimizations (--emit llvm-ir -C no-prepopulate-passes) is the same for both-C opt-level=2and-C opt-level=3.Some additional info that might be helpful:
codegen-units = 1);1.41.0release (no idea what makes it different);cargo-bisect-rustcsays the regression first happened in the2019-12-12nightly, specifically in this commit. This seems suspicious to me, given that1.40.0, which does not exhibit the problem, was released after this date.I'm attaching the program inline in case the GitHub repo doesn't work (if you want to compile it without Cargo, use
rustc -C opt-level=3 main.rs):