Skip to content

Commit 238ed49

Browse files
committed
detect UB: overflow in copy/write_bytes
1 parent 8acfafe commit 238ed49

File tree

3 files changed

+24
-4
lines changed

3 files changed

+24
-4
lines changed

src/shims/intrinsics.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use std::convert::TryFrom;
44
use rustc::mir;
55
use rustc::mir::interpret::{InterpResult, PointerArithmetic};
66
use rustc::ty;
7-
use rustc::ty::layout::{Align, LayoutOf, Size};
7+
use rustc::ty::layout::{Align, LayoutOf};
88
use rustc_apfloat::Float;
99
use rustc_span::source_map::Span;
1010

@@ -226,11 +226,11 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
226226
=> {
227227
let elem_ty = substs.type_at(0);
228228
let elem_layout = this.layout_of(elem_ty)?;
229-
let elem_size = elem_layout.size.bytes();
230229
let count = this.read_scalar(args[2])?.to_machine_usize(this)?;
231230
let elem_align = elem_layout.align.abi;
232231

233-
let size = Size::from_bytes(count) * elem_size;
232+
let size = elem_layout.size.checked_mul(count, this)
233+
.ok_or_else(|| err_ub_format!("overflow computing total size of `{}`", intrinsic_name))?;
234234
let src = this.read_scalar(args[0])?.not_undef()?;
235235
let src = this.memory.check_ptr_access(src, size, elem_align)?;
236236
let dest = this.read_scalar(args[1])?.not_undef()?;
@@ -493,7 +493,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
493493
let val_byte = this.read_scalar(args[1])?.to_u8()?;
494494
let ptr = this.read_scalar(args[0])?.not_undef()?;
495495
let count = this.read_scalar(args[2])?.to_machine_usize(this)?;
496-
let byte_count = ty_layout.size * count;
496+
let byte_count = ty_layout.size.checked_mul(count, this)
497+
.ok_or_else(|| err_ub_format!("overflow computing total size of `write_bytes`"))?;
497498
this.memory
498499
.write_bytes(ptr, iter::repeat(val_byte).take(byte_count.bytes() as usize))?;
499500
}

tests/compile-fail/copy_overflow.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// error-pattern: overflow computing total size of `copy`
2+
use std::mem;
3+
4+
fn main() {
5+
let x = 0;
6+
let mut y = 0;
7+
unsafe {
8+
(&mut y as *mut i32).copy_from(&x, 1usize << (mem::size_of::<usize>() * 8 - 1));
9+
}
10+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// error-pattern: overflow computing total size of `write_bytes`
2+
use std::mem;
3+
4+
fn main() {
5+
let mut y = 0;
6+
unsafe {
7+
(&mut y as *mut i32).write_bytes(0u8, 1usize << (mem::size_of::<usize>() * 8 - 1));
8+
}
9+
}

0 commit comments

Comments
 (0)