Auto merge of #2278 - RalfJung:rustup, r=RalfJung

Rustup
This commit is contained in:
bors 2022-06-28 01:53:06 +00:00
commit aefaa5b6f0
6 changed files with 21 additions and 35 deletions

View File

@ -1 +1 @@
8aab472d52ba7314dc193c73abcd384e2586123c
7f08d04d60d03e1a52dae61ce6aa50996898702b

View File

@ -76,27 +76,17 @@ fn alloc_id_from_addr(ecx: &MiriEvalContext<'mir, 'tcx>, addr: u64) -> Option<Al
// This never overflows because `addr >= glb`
let offset = addr - glb;
// If the offset exceeds the size of the allocation, don't use this `alloc_id`.
if offset
<= ecx
.get_alloc_size_and_align(alloc_id, AllocCheck::MaybeDead)
.unwrap()
.0
.bytes()
{
Some(alloc_id)
} else {
None
}
let size = ecx.get_alloc_info(alloc_id).0;
if offset <= size.bytes() { Some(alloc_id) } else { None }
}
}?;
// We only use this provenance if it has been exposed, *and* is still live.
if global_state.exposed.contains(&alloc_id) {
// FIXME: this catches `InterpError`, which we should not usually do.
// We might need a proper fallible API from `memory.rs` to avoid this though.
if ecx.get_alloc_size_and_align(alloc_id, AllocCheck::Live).is_ok() {
return Some(alloc_id);
let (_size, _align, kind) = ecx.get_alloc_info(alloc_id);
match kind {
AllocKind::LiveData | AllocKind::Function => return Some(alloc_id),
AllocKind::Dead => {}
}
}
@ -174,9 +164,8 @@ fn alloc_base_addr(ecx: &MiriEvalContext<'mir, 'tcx>, alloc_id: AllocId) -> u64
Entry::Occupied(entry) => *entry.get(),
Entry::Vacant(entry) => {
// There is nothing wrong with a raw pointer being cast to an integer only after
// it became dangling. Hence `MaybeDead`.
let (size, align) =
ecx.get_alloc_size_and_align(alloc_id, AllocCheck::MaybeDead).unwrap();
// it became dangling. Hence we allow dead allocations.
let (size, align, _kind) = ecx.get_alloc_info(alloc_id);
// This allocation does not have a base address yet, pick one.
// Leave some space to the previous allocation, to give it some chance to be less aligned.

View File

@ -87,7 +87,7 @@ fn align_offset(
let ptr = this.read_pointer(ptr_op)?;
if let Ok((alloc_id, _offset, _)) = this.ptr_try_get_alloc_id(ptr) {
// Only do anything if we can identify the allocation this goes to.
let (_, cur_align) = this.get_alloc_size_and_align(alloc_id, AllocCheck::MaybeDead)?;
let (_size, cur_align, _kind) = this.get_alloc_info(alloc_id);
if cur_align.bytes() >= req_align {
// If the allocation alignment is at least the required alignment we use the
// real implementation.

View File

@ -849,8 +849,7 @@ fn reborrow(
log_creation(this, current_span, alloc_id, base_offset, orig_tag)?;
// Ensure we bail out if the pointer goes out-of-bounds (see miri#1050).
let (alloc_size, _) =
this.get_alloc_size_and_align(alloc_id, AllocCheck::Dereferenceable)?;
let (alloc_size, _) = this.get_live_alloc_size_and_align(alloc_id)?;
if base_offset + size > alloc_size {
throw_ub!(PointerOutOfBounds {
alloc_id,
@ -1088,18 +1087,16 @@ fn expose_tag(&mut self, alloc_id: AllocId, tag: SbTag) {
// Function pointers and dead objects don't have an alloc_extra so we ignore them.
// This is okay because accessing them is UB anyway, no need for any Stacked Borrows checks.
// NOT using `get_alloc_extra_mut` since this might be a read-only allocation!
// FIXME: this catches `InterpError`, which we should not usually do.
// We might need a proper fallible API from `memory.rs` to avoid this though.
match this.get_alloc_extra(alloc_id) {
Ok(alloc_extra) => {
let (_size, _align, kind) = this.get_alloc_info(alloc_id);
match kind {
AllocKind::LiveData => {
// This should have alloc_extra data.
let alloc_extra = this.get_alloc_extra(alloc_id).unwrap();
trace!("Stacked Borrows tag {tag:?} exposed in {alloc_id}");
alloc_extra.stacked_borrows.as_ref().unwrap().borrow_mut().exposed_tags.insert(tag);
}
Err(err) => {
trace!(
"Not exposing Stacked Borrows tag {tag:?} due to error \
when accessing {alloc_id}: {err}"
);
AllocKind::Function | AllocKind::Dead => {
// No stacked borrows on these allocations.
}
}
}

View File

@ -2,7 +2,7 @@ fn f() {}
fn main() {
let x: u8 = unsafe {
*std::mem::transmute::<fn(), *const u8>(f) //~ ERROR contains a function
*std::mem::transmute::<fn(), *const u8>(f) //~ ERROR out-of-bounds
};
panic!("this should never print: {}", x);
}

View File

@ -1,8 +1,8 @@
error: Undefined Behavior: accessing ALLOC which contains a function
error: Undefined Behavior: dereferencing pointer failed: ALLOC has size 0, so pointer to 1 byte starting at offset 0 is out-of-bounds
--> $DIR/deref_fn_ptr.rs:LL:CC
|
LL | *std::mem::transmute::<fn(), *const u8>(f)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ accessing ALLOC which contains a function
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ dereferencing pointer failed: ALLOC has size 0, so pointer to 1 byte starting at offset 0 is out-of-bounds
|
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information