I'm using Rust with KLEE and kept getting out-of-bounds error in memcpy of compiler_builtins.
Turns out that compiler_builtins' memcpy copies word by word, and cause out-of-bound if the object size is not a multiple of the size of usize
.
Relevant compiler_builtins code:
// This will read (but won't use) bytes out of bound.
// cfg needed because not all targets will have atomic loads that can be lowered
// (e.g. BPF, MSP430), or provided by an external library (e.g. RV32I)
#[cfg(target_has_atomic_load_store = "ptr")]
let mut prev_word = core::intrinsics::atomic_load_unordered(src_aligned);
#[cfg(not(target_has_atomic_load_store = "ptr"))]
let mut prev_word = core::ptr::read_volatile(src_aligned);
while dest_usize < dest_end {
src_aligned = src_aligned.add(1);
let cur_word = *src_aligned;
#[cfg(target_endian = "little")]
let resembled = prev_word >> shift | cur_word << (WORD_SIZE * 8 - shift);
#[cfg(target_endian = "big")]
let resembled = prev_word << shift | cur_word >> (WORD_SIZE * 8 - shift);
prev_word = cur_word;
*dest_usize = resembled;
dest_usize = dest_usize.add(1);
}
}
Does Rust assume the allocator implementation aligns the size of the object to size of usize
?
NVM. It seems it reads out-of-bound as the comments say, but do not perform out-of-bound write.
I'll have to align up size before calling malloc.
I ended up forcing klee to use it's own version of memcpy.
I could've also changed klee to allocate size aligned up to usize (for global/stack/heap objects), but then I could miss off-by-one errors.
system
Closed
September 8, 2022, 10:16am
3
This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.