[msan] Add __msan_copy_shadow interface function.

This can be used to annotate copies of memory that are not observed by MSan.

llvm-svn: 250124
This commit is contained in:
Evgeniy Stepanov 2015-10-12 23:20:24 +00:00
parent daedc12172
commit c7ee62c561
4 changed files with 48 additions and 0 deletions

View File

@ -98,6 +98,12 @@ extern "C" {
/* Deprecated. Call __sanitizer_set_death_callback instead. */
void __msan_set_death_callback(void (*callback)(void));
/* Update shadow for the application copy of size bytes from src to dst.
Src and dst are application addresses. This function does not copy the
actual application memory, it only updates shadow and origin for such
copy. Source and destination regions can overlap. */
void __msan_copy_shadow(const volatile void *dst, const volatile void *src,
size_t size);
#ifdef __cplusplus
} // extern "C"
#endif

View File

@ -1011,6 +1011,11 @@ void __msan_allocated_memory(const void *data, uptr size) {
}
}
void __msan_copy_shadow(void *dest, const void *src, uptr n) {
GET_STORE_STACK_TRACE;
MoveShadowAndOrigin(dest, src, n, &stack);
}
void __sanitizer_dtor_callback(const void *data, uptr size) {
GET_MALLOC_STACK_TRACE;
if (flags()->poison_in_dtor) {

View File

@ -161,6 +161,9 @@ void __sanitizer_unaligned_store64(uu64 *p, u64 x);
SANITIZER_INTERFACE_ATTRIBUTE
void __msan_set_death_callback(void (*callback)(void));
SANITIZER_INTERFACE_ATTRIBUTE
void __msan_copy_shadow(void *dst, const void *src, uptr size);
} // extern "C"
#endif // MSAN_INTERFACE_INTERNAL_H

View File

@ -0,0 +1,34 @@
// Test that __msan_copy_shadow copies shadow, updates origin and does not touch
// the application memory.
// RUN: %clangxx_msan -fsanitize-memory-track-origins=0 -O0 %s -o %t && not %run %t 2>&1
// RUN: %clangxx_msan -fsanitize-memory-track-origins=2 -O0 %s -o %t && not %run %t 2>&1 | FileCheck %s
#include <assert.h>
#include <string.h>
#include <sanitizer/msan_interface.h>
int main() {
char *a = new char[4];
char *b = new char[4];
a[1] = 1;
a[3] = 2;
memset(b, 42, 4);
// Test that __msan_copy_shadow does not touch the contents of b[].
__msan_copy_shadow(b, a, 4);
__msan_unpoison(b, 4);
assert(b[0] == 42 && b[1] == 42 && b[2] == 42 && b[3] == 42);
// Test that __msan_copy_shadow correctly updates shadow and origin of b[].
__msan_copy_shadow(b, a, 4);
assert(__msan_test_shadow(b, 4) == 0);
assert(__msan_test_shadow(b + 1, 3) == 1);
assert(__msan_test_shadow(b + 3, 1) == -1);
__msan_check_mem_is_initialized(b, 4);
// CHECK: use-of-uninitialized-value
// CHECK: {{in main.*msan_copy_shadow.cc:}}[[@LINE-2]]
// CHECK: Uninitialized value was stored to memory at
// CHECK: {{in main.*msan_copy_shadow.cc:}}[[@LINE-8]]
// CHECK: Uninitialized value was created by a heap allocation
// CHECK: {{in main.*msan_copy_shadow.cc:}}[[@LINE-22]]
}