Skip to content

Commit 9a51109

Browse files
committed
add test to make Miri able to detect OOB in memmove
1 parent 96c4e09 commit 9a51109

File tree

2 files changed

+21
-4
lines changed

2 files changed

+21
-4
lines changed

src/mem/impls.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ unsafe fn load_aligned_partial(src: *const usize, load_sz: usize) -> usize {
5454
let chunk_sz = core::mem::size_of::<$ty>();
5555
if (load_sz & chunk_sz) != 0 {
5656
// Since we are doing the large reads first, this must still be aligned to `chunk_sz`.
57-
*(&raw mut out).byte_add(i).cast::<$ty>() = *src.byte_add(i).cast::<$ty>();
57+
*(&raw mut out).wrapping_byte_add(i).cast::<$ty>() = *src.wrapping_byte_add(i).cast::<$ty>();
5858
i |= chunk_sz;
5959
}
6060
)+};
@@ -83,7 +83,7 @@ unsafe fn load_aligned_end_partial(src: *const usize, load_sz: usize) -> usize {
8383
if (load_sz & chunk_sz) != 0 {
8484
// Since we are doing the small reads first, `start_shift + i` has in the mean
8585
// time become aligned to `chunk_sz`.
86-
*(&raw mut out).byte_add(start_shift + i).cast::<$ty>() = *src.byte_add(start_shift + i).cast::<$ty>();
86+
*(&raw mut out).wrapping_byte_add(start_shift + i).cast::<$ty>() = *src.wrapping_byte_add(start_shift + i).cast::<$ty>();
8787
i |= chunk_sz;
8888
}
8989
)+};
@@ -137,7 +137,7 @@ pub unsafe fn copy_forward(mut dest: *mut u8, mut src: *const u8, mut n: usize)
137137
let shift = offset * 8;
138138

139139
// Realign src
140-
let mut src_aligned = src.byte_sub(offset) as *mut usize;
140+
let mut src_aligned = src.wrapping_byte_sub(offset) as *mut usize;
141141
let mut prev_word = load_aligned_end_partial(src_aligned, WORD_SIZE - offset);
142142

143143
while dest_usize.wrapping_add(1) < dest_end {
@@ -249,7 +249,7 @@ pub unsafe fn copy_backward(dest: *mut u8, src: *const u8, mut n: usize) {
249249
let shift = offset * 8;
250250

251251
// Realign src
252-
let mut src_aligned = src.byte_sub(offset) as *mut usize;
252+
let mut src_aligned = src.wrapping_byte_sub(offset) as *mut usize;
253253
let mut prev_word = load_aligned_partial(src_aligned, offset);
254254

255255
while dest_start.wrapping_add(1) < dest_usize {

testcrate/tests/mem.rs

+17
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,23 @@ fn memmove_backward_aligned() {
230230
}
231231
}
232232

233+
#[test]
234+
fn memmove_misaligned_bounds() {
235+
// The above test have the downside that the addresses surrounding the range-to-copy are all
236+
// still in-bounds, so Miri would not actually complain about OOB accesses. So we also test with
237+
// an array that has just the right size. We test a few times to avoid it being accidentally
238+
// aligned.
239+
for _ in 0..8 {
240+
let mut arr1 = [0u8; 17];
241+
let mut arr2 = [0u8; 17];
242+
unsafe {
243+
// Copy both ways so we hit both the forward and backward cases.
244+
memmove(arr1.as_mut_ptr(), arr2.as_mut_ptr(), 17);
245+
memmove(arr2.as_mut_ptr(), arr1.as_mut_ptr(), 17);
246+
}
247+
}
248+
}
249+
233250
#[test]
234251
fn memset_backward_misaligned_nonaligned_start() {
235252
let mut arr = gen_arr::<32>();

0 commit comments

Comments
 (0)