Skip to content

Commit 15a0004

Browse files
authored
Merge pull request #470 from RalfJung/ptr-offset
only allow 0-offset on integer pointers
2 parents 5a496dd + a439262 commit 15a0004

File tree

3 files changed

+22
-11
lines changed

3 files changed

+22
-11
lines changed

src/operator.rs

+7-11
Original file line numberDiff line numberDiff line change
@@ -281,14 +281,6 @@ impl<'a, 'mir, 'tcx> EvalContextExt<'tcx> for EvalContext<'a, 'mir, 'tcx, super:
281281
pointee_ty: Ty<'tcx>,
282282
offset: i64,
283283
) -> EvalResult<'tcx, Scalar> {
284-
if ptr.is_null() {
285-
// NULL pointers must only be offset by 0
286-
return if offset == 0 {
287-
Ok(ptr)
288-
} else {
289-
err!(InvalidNullPointerUsage)
290-
};
291-
}
292284
// FIXME: assuming here that type size is < i64::max_value()
293285
let pointee_size = self.layout_of(pointee_ty)?.size.bytes() as i64;
294286
let offset = offset.checked_mul(pointee_size).ok_or_else(|| EvalErrorKind::Overflow(mir::BinOp::Mul))?;
@@ -301,9 +293,13 @@ impl<'a, 'mir, 'tcx> EvalContextExt<'tcx> for EvalContext<'a, 'mir, 'tcx, super:
301293
self.memory.check_bounds_ptr(ptr, false)?;
302294
Ok(Scalar::Ptr(ptr))
303295
} else {
304-
// An integer pointer. They can move around freely, as long as they do not overflow
305-
// (which ptr_signed_offset checks).
306-
ptr.ptr_signed_offset(offset, self)
296+
// An integer pointer. They can only be offset by 0, and we pretend there
297+
// is a little zero-sized allocation here.
298+
if offset == 0 {
299+
Ok(ptr)
300+
} else {
301+
err!(InvalidPointerMath)
302+
}
307303
}
308304
}
309305
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
// error-pattern: invalid arithmetic on pointers
2+
3+
fn main() {
4+
// Can't offset an integer pointer by non-zero offset.
5+
unsafe {
6+
let _ = (1 as *mut u8).offset(1);
7+
}
8+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
// error-pattern: outside bounds of allocation
2+
3+
fn main() {
4+
let x = Box::into_raw(Box::new(0u32));
5+
let x = x.wrapping_offset(8); // okay, this has no inbounds tag
6+
let _x = unsafe { x.offset(0) }; // UB despite offset 0, the pointer is not inbounds of the only object it can point to
7+
}

0 commit comments

Comments
 (0)