From 1fe310c8ba663f1046daca57530077e87bf3665d Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Wed, 12 Jul 2017 19:29:16 -0700 Subject: [PATCH] Memory::read_ptr has to check for relocations on the edges --- src/memory.rs | 1 + tests/compile-fail/reading_half_a_pointer.rs | 29 ++++++++++++++++++++ 2 files changed, 30 insertions(+) create mode 100644 tests/compile-fail/reading_half_a_pointer.rs diff --git a/src/memory.rs b/src/memory.rs index caf7f3a6516..710912d64d7 100644 --- a/src/memory.rs +++ b/src/memory.rs @@ -745,6 +745,7 @@ pub fn read_ptr(&self, ptr: MemoryPointer) -> EvalResult<'tcx, Pointer> { if self.check_defined(ptr, size).is_err() { return Ok(PrimVal::Undef.into()); } + self.check_relocation_edges(ptr, size)?; // Make sure we don't read part of a pointer as a pointer let endianess = self.endianess(); let bytes = self.get_bytes_unchecked(ptr, size, size)?; let offset = read_target_uint(endianess, bytes).unwrap(); diff --git a/tests/compile-fail/reading_half_a_pointer.rs b/tests/compile-fail/reading_half_a_pointer.rs new file mode 100644 index 00000000000..cc41b52f333 --- /dev/null +++ b/tests/compile-fail/reading_half_a_pointer.rs @@ -0,0 +1,29 @@ +#![allow(dead_code)] + +// We use packed structs to get around alignment restrictions +#[repr(packed)] +struct Data { + pad: u8, + ptr: &'static i32, +} + +// But we need to gurantee some alignment +struct Wrapper { + align: u64, + data: Data, +} + +static G : i32 = 0; + +fn main() { + let mut w = Wrapper { align: 0, data: Data { pad: 0, ptr: &G } }; + + // Get a pointer to the beginning of the Data struct (one u8 byte, then the pointer bytes). + // Thanks to the wrapper, we know this is aligned-enough to perform a load at ptr size. + // We load at pointer type, so having a relocation is okay -- but here, the relocation + // starts 1 byte to the right, so using it would actually be wrong! + let d_alias = &mut w.data as *mut _ as *mut *const u8; + unsafe { + let _x = *d_alias; //~ ERROR: tried to access part of a pointer value as raw bytes + } +}