A MIR transform that checks pointers are aligned
This commit is contained in:
parent
e216300876
commit
8ccf53332e
34 changed files with 360 additions and 20 deletions
|
|
@ -169,7 +169,7 @@ fn check_rvalue<'tcx>(
|
|||
Err((span, "unsizing casts are not allowed in const fn".into()))
|
||||
}
|
||||
},
|
||||
Rvalue::Cast(CastKind::PointerExposeAddress, _, _) => {
|
||||
Rvalue::Cast(CastKind::PointerExposeAddress | CastKind::PointerAddress, _, _) => {
|
||||
Err((span, "casting pointers to ints is unstable in const fn".into()))
|
||||
},
|
||||
Rvalue::Cast(CastKind::DynStar, _, _) => {
|
||||
|
|
|
|||
|
|
@ -220,6 +220,34 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
|||
},
|
||||
)?;
|
||||
}
|
||||
MisalignedPointerDereference { required, found } => {
|
||||
// Forward to `panic_misaligned_pointer_dereference` lang item.
|
||||
|
||||
// First arg: required.
|
||||
let required = this.read_scalar(&this.eval_operand(required, None)?)?;
|
||||
// Second arg: found.
|
||||
let found = this.read_scalar(&this.eval_operand(found, None)?)?;
|
||||
|
||||
// Call the lang item.
|
||||
let panic_misaligned_pointer_dereference =
|
||||
this.tcx.lang_items().panic_misaligned_pointer_dereference_fn().unwrap();
|
||||
let panic_misaligned_pointer_dereference =
|
||||
ty::Instance::mono(this.tcx.tcx, panic_misaligned_pointer_dereference);
|
||||
this.call_function(
|
||||
panic_misaligned_pointer_dereference,
|
||||
Abi::Rust,
|
||||
&[required.into(), found.into()],
|
||||
None,
|
||||
StackPopCleanup::Goto {
|
||||
ret: None,
|
||||
unwind: match unwind {
|
||||
Some(cleanup) => StackPopUnwind::Cleanup(cleanup),
|
||||
None => StackPopUnwind::Skip,
|
||||
},
|
||||
},
|
||||
)?;
|
||||
}
|
||||
|
||||
_ => {
|
||||
// Forward everything else to `panic` lang item.
|
||||
this.start_panic(
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
//@normalize-stderr-test: "\| +\^+" -> "| ^"
|
||||
//@compile-flags: -Cdebug-assertions=no
|
||||
|
||||
fn main() {
|
||||
// No retry needed, this fails reliably.
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
//@compile-flags: -Zmiri-symbolic-alignment-check
|
||||
//@compile-flags: -Zmiri-symbolic-alignment-check -Cdebug-assertions=no
|
||||
#![feature(core_intrinsics)]
|
||||
|
||||
fn main() {
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
//@compile-flags: -Cdebug-assertions=no
|
||||
|
||||
#[repr(transparent)]
|
||||
struct HasDrop(u8);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
// should find the bug even without validation and stacked borrows, but gets masked by optimizations
|
||||
//@compile-flags: -Zmiri-disable-validation -Zmiri-disable-stacked-borrows -Zmir-opt-level=0
|
||||
//@compile-flags: -Zmiri-disable-validation -Zmiri-disable-stacked-borrows -Zmir-opt-level=0 -Cdebug-assertions=no
|
||||
|
||||
#[repr(align(256))]
|
||||
#[derive(Debug)]
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
//@compile-flags: -Zmiri-symbolic-alignment-check -Zmiri-permissive-provenance
|
||||
//@compile-flags: -Zmiri-symbolic-alignment-check -Zmiri-permissive-provenance -Cdebug-assertions=no
|
||||
// With the symbolic alignment check, even with intptrcast and without
|
||||
// validation, we want to be *sure* to catch bugs that arise from pointers being
|
||||
// insufficiently aligned. The only way to achieve that is not not let programs
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
// This should fail even without validation/SB
|
||||
//@compile-flags: -Zmiri-disable-validation -Zmiri-disable-stacked-borrows
|
||||
//@compile-flags: -Zmiri-disable-validation -Zmiri-disable-stacked-borrows -Cdebug-assertions=no
|
||||
|
||||
#![allow(dead_code, unused_variables)]
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
// This should fail even without validation or Stacked Borrows.
|
||||
//@compile-flags: -Zmiri-disable-validation -Zmiri-disable-stacked-borrows
|
||||
//@compile-flags: -Zmiri-disable-validation -Zmiri-disable-stacked-borrows -Cdebug-assertions=no
|
||||
|
||||
fn main() {
|
||||
// Try many times as this might work by chance.
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
// This should fail even without validation or Stacked Borrows.
|
||||
//@compile-flags: -Zmiri-disable-validation -Zmiri-disable-stacked-borrows
|
||||
//@compile-flags: -Zmiri-disable-validation -Zmiri-disable-stacked-borrows -Cdebug-assertions=no
|
||||
|
||||
fn main() {
|
||||
// No retry needed, this fails reliably.
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
// This should fail even without validation or Stacked Borrows.
|
||||
//@compile-flags: -Zmiri-disable-validation -Zmiri-disable-stacked-borrows
|
||||
//@compile-flags: -Zmiri-disable-validation -Zmiri-disable-stacked-borrows -Cdebug-assertions=no
|
||||
|
||||
fn main() {
|
||||
// Try many times as this might work by chance.
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
// This should fail even without validation or Stacked Borrows.
|
||||
//@compile-flags: -Zmiri-disable-validation -Zmiri-disable-stacked-borrows
|
||||
//@compile-flags: -Zmiri-disable-validation -Zmiri-disable-stacked-borrows -Cdebug-assertions=no
|
||||
|
||||
fn main() {
|
||||
// Make sure we notice when a u16 is loaded at offset 1 into a u8 allocation.
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
// This should fail even without validation or Stacked Borrows.
|
||||
//@compile-flags: -Zmiri-disable-validation -Zmiri-disable-stacked-borrows
|
||||
//@compile-flags: -Zmiri-disable-validation -Zmiri-disable-stacked-borrows -Cdebug-assertions=no
|
||||
use std::ptr;
|
||||
|
||||
fn main() {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
// This should fail even without validation
|
||||
// Some optimizations remove ZST accesses, thus masking this UB.
|
||||
//@compile-flags: -Zmir-opt-level=0 -Zmiri-disable-validation
|
||||
//@compile-flags: -Zmir-opt-level=0 -Zmiri-disable-validation -Cdebug-assertions=no
|
||||
|
||||
fn main() {
|
||||
// Try many times as this might work by chance.
|
||||
|
|
|
|||
9
src/tools/miri/tests/panic/alignment-assertion.rs
Normal file
9
src/tools/miri/tests/panic/alignment-assertion.rs
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
//@compile-flags: -Zmiri-disable-alignment-check -Cdebug-assertions=yes
|
||||
|
||||
fn main() {
|
||||
let mut x = [0u32; 2];
|
||||
let ptr: *mut u8 = x.as_mut_ptr().cast::<u8>();
|
||||
unsafe {
|
||||
*(ptr.add(1).cast::<u32>()) = 42;
|
||||
}
|
||||
}
|
||||
2
src/tools/miri/tests/panic/alignment-assertion.stderr
Normal file
2
src/tools/miri/tests/panic/alignment-assertion.stderr
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
thread 'main' panicked at 'misaligned pointer dereference: address must be a multiple of 0x4 but is $HEX', $DIR/alignment-assertion.rs:LL:CC
|
||||
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
//@revisions: stack tree
|
||||
//@[tree]compile-flags: -Zmiri-tree-borrows
|
||||
//@compile-flags: -Zmiri-disable-alignment-check
|
||||
//@compile-flags: -Zmiri-disable-alignment-check -Cdebug-assertions=no
|
||||
|
||||
fn main() {
|
||||
let mut x = [0u8; 20];
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue