forked from OSchip/llvm-project
[msan] Cleanup public interface header.
Moved everything users are not supposed to use to a private interface header. Documented all public interfaces. Made them safe to use even if built without MemorySanitizer. llvm-svn: 173800
This commit is contained in:
parent
019ef67a97
commit
eac7f934f0
|
@ -24,103 +24,99 @@ using __sanitizer::u32;
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// FIXME: document all interface functions.
|
#if defined(__has_feature) && __has_feature(memory_sanitizer)
|
||||||
|
|
||||||
SANITIZER_INTERFACE_ATTRIBUTE
|
/* Returns a string describing a stack origin.
|
||||||
int __msan_get_track_origins();
|
Return NULL if the origin is invalid, or is not a stack origin. */
|
||||||
|
SANITIZER_INTERFACE_ATTRIBUTE
|
||||||
|
const char *__msan_get_origin_descr_if_stack(u32 id);
|
||||||
|
|
||||||
SANITIZER_INTERFACE_ATTRIBUTE
|
|
||||||
void __msan_init();
|
|
||||||
|
|
||||||
// Print a warning and maybe return.
|
/* Set raw origin for the memory range. */
|
||||||
// This function can die based on flags()->exit_code.
|
SANITIZER_INTERFACE_ATTRIBUTE
|
||||||
SANITIZER_INTERFACE_ATTRIBUTE
|
void __msan_set_origin(void *a, uptr size, u32 origin);
|
||||||
void __msan_warning();
|
|
||||||
|
|
||||||
// Print a warning and die.
|
/* Get raw origin for an address. */
|
||||||
// Intrumentation inserts calls to this function when building in "fast" mode
|
SANITIZER_INTERFACE_ATTRIBUTE
|
||||||
// (i.e. -mllvm -msan-keep-going)
|
u32 __msan_get_origin(void *a);
|
||||||
SANITIZER_INTERFACE_ATTRIBUTE __attribute__((noreturn))
|
|
||||||
void __msan_warning_noreturn();
|
|
||||||
|
|
||||||
SANITIZER_INTERFACE_ATTRIBUTE
|
/* Returns non-zero if tracking origins. */
|
||||||
void __msan_unpoison(void *a, uptr size);
|
SANITIZER_INTERFACE_ATTRIBUTE
|
||||||
SANITIZER_INTERFACE_ATTRIBUTE
|
int __msan_get_track_origins();
|
||||||
void __msan_clear_and_unpoison(void *a, uptr size);
|
|
||||||
SANITIZER_INTERFACE_ATTRIBUTE
|
|
||||||
void* __msan_memcpy(void *dst, const void *src, uptr size);
|
|
||||||
SANITIZER_INTERFACE_ATTRIBUTE
|
|
||||||
void* __msan_memset(void *s, int c, uptr n);
|
|
||||||
SANITIZER_INTERFACE_ATTRIBUTE
|
|
||||||
void* __msan_memmove(void* dest, const void* src, uptr n);
|
|
||||||
SANITIZER_INTERFACE_ATTRIBUTE
|
|
||||||
void __msan_copy_poison(void *dst, const void *src, uptr size);
|
|
||||||
SANITIZER_INTERFACE_ATTRIBUTE
|
|
||||||
void __msan_copy_origin(void *dst, const void *src, uptr size);
|
|
||||||
SANITIZER_INTERFACE_ATTRIBUTE
|
|
||||||
void __msan_move_poison(void *dst, const void *src, uptr size);
|
|
||||||
SANITIZER_INTERFACE_ATTRIBUTE
|
|
||||||
void __msan_poison(void *a, uptr size);
|
|
||||||
SANITIZER_INTERFACE_ATTRIBUTE
|
|
||||||
void __msan_poison_stack(void *a, uptr size);
|
|
||||||
|
|
||||||
// Copy size bytes from src to dst and unpoison the result.
|
/* Returns the origin id of the latest UMR in the calling thread. */
|
||||||
// Useful to implement unsafe loads.
|
SANITIZER_INTERFACE_ATTRIBUTE
|
||||||
SANITIZER_INTERFACE_ATTRIBUTE
|
u32 __msan_get_umr_origin();
|
||||||
void __msan_load_unpoisoned(void *src, uptr size, void *dst);
|
|
||||||
|
|
||||||
// Returns the offset of the first (at least partially) poisoned byte,
|
/* Make memory region fully initialized (without changing its contents). */
|
||||||
// or -1 if the whole range is good.
|
SANITIZER_INTERFACE_ATTRIBUTE
|
||||||
SANITIZER_INTERFACE_ATTRIBUTE
|
void __msan_unpoison(void *a, uptr size);
|
||||||
sptr __msan_test_shadow(const void *x, uptr size);
|
|
||||||
|
|
||||||
SANITIZER_INTERFACE_ATTRIBUTE
|
/* Make memory region fully uninitialized (without changing its contents). */
|
||||||
void __msan_set_origin(void *a, uptr size, u32 origin);
|
SANITIZER_INTERFACE_ATTRIBUTE
|
||||||
SANITIZER_INTERFACE_ATTRIBUTE
|
void __msan_poison(void *a, uptr size);
|
||||||
void __msan_set_alloca_origin(void *a, uptr size, const char *descr);
|
|
||||||
SANITIZER_INTERFACE_ATTRIBUTE
|
|
||||||
u32 __msan_get_origin(void *a);
|
|
||||||
|
|
||||||
SANITIZER_INTERFACE_ATTRIBUTE
|
/* Make memory region partially uninitialized (without changing its contents).
|
||||||
void __msan_clear_on_return();
|
*/
|
||||||
|
SANITIZER_INTERFACE_ATTRIBUTE
|
||||||
|
void __msan_partial_poison(void* data, void* shadow, uptr size);
|
||||||
|
|
||||||
// Default: -1 (don't exit on error).
|
/* Returns the offset of the first (at least partially) poisoned byte in the
|
||||||
SANITIZER_INTERFACE_ATTRIBUTE
|
memory range, or -1 if the whole range is good. */
|
||||||
void __msan_set_exit_code(int exit_code);
|
SANITIZER_INTERFACE_ATTRIBUTE
|
||||||
|
sptr __msan_test_shadow(const void *x, uptr size);
|
||||||
|
|
||||||
SANITIZER_INTERFACE_ATTRIBUTE
|
/* Set exit code when error(s) were detected.
|
||||||
int __msan_set_poison_in_malloc(int do_poison);
|
Value of 0 means don't change the program exit code. */
|
||||||
|
SANITIZER_INTERFACE_ATTRIBUTE
|
||||||
|
void __msan_set_exit_code(int exit_code);
|
||||||
|
|
||||||
// For testing.
|
/* For testing:
|
||||||
SANITIZER_INTERFACE_ATTRIBUTE
|
__msan_set_expect_umr(1);
|
||||||
void __msan_set_expect_umr(int expect_umr);
|
... some buggy code ...
|
||||||
SANITIZER_INTERFACE_ATTRIBUTE
|
__msan_set_expect_umr(0);
|
||||||
void __msan_break_optimization(void *x);
|
The last line will verify that a UMR happened. */
|
||||||
SANITIZER_INTERFACE_ATTRIBUTE
|
SANITIZER_INTERFACE_ATTRIBUTE
|
||||||
void __msan_print_shadow(const void *x, uptr size);
|
void __msan_set_expect_umr(int expect_umr);
|
||||||
SANITIZER_INTERFACE_ATTRIBUTE
|
|
||||||
void __msan_print_param_shadow();
|
|
||||||
SANITIZER_INTERFACE_ATTRIBUTE
|
|
||||||
int __msan_has_dynamic_component();
|
|
||||||
|
|
||||||
// Returns x such that %fs:x is the first byte of __msan_retval_tls.
|
/* Print shadow and origin for the memory range to stdout in a human-readable
|
||||||
SANITIZER_INTERFACE_ATTRIBUTE
|
format. */
|
||||||
int __msan_get_retval_tls_offset();
|
SANITIZER_INTERFACE_ATTRIBUTE
|
||||||
SANITIZER_INTERFACE_ATTRIBUTE
|
void __msan_print_shadow(const void *x, uptr size);
|
||||||
int __msan_get_param_tls_offset();
|
|
||||||
|
|
||||||
// For testing.
|
/* Print current function arguments shadow and origin to stdout in a
|
||||||
SANITIZER_INTERFACE_ATTRIBUTE
|
human-readable format. */
|
||||||
u32 __msan_get_origin_tls();
|
SANITIZER_INTERFACE_ATTRIBUTE
|
||||||
SANITIZER_INTERFACE_ATTRIBUTE
|
void __msan_print_param_shadow();
|
||||||
const char *__msan_get_origin_descr_if_stack(u32 id);
|
|
||||||
SANITIZER_INTERFACE_ATTRIBUTE
|
|
||||||
void __msan_partial_poison(void* data, void* shadow, uptr size);
|
|
||||||
|
|
||||||
// Tell MSan about newly allocated memory (ex.: custom allocator).
|
/* Returns true if running under a dynamic tool (DynamoRio-based). */
|
||||||
// Memory will be marked uninitialized, with origin at the call site.
|
SANITIZER_INTERFACE_ATTRIBUTE
|
||||||
SANITIZER_INTERFACE_ATTRIBUTE
|
int __msan_has_dynamic_component();
|
||||||
void __msan_allocated_memory(void* data, uptr size);
|
|
||||||
|
/* Tell MSan about newly allocated memory (ex.: custom allocator).
|
||||||
|
Memory will be marked uninitialized, with origin at the call site. */
|
||||||
|
SANITIZER_INTERFACE_ATTRIBUTE
|
||||||
|
void __msan_allocated_memory(void* data, uptr size);
|
||||||
|
|
||||||
|
#else // __has_feature(memory_sanitizer)
|
||||||
|
|
||||||
|
#define __msan_get_origin_descr_if_stack(u32 id) ((const char*)0)
|
||||||
|
#define __msan_set_origin(void *a, uptr size, u32 origin)
|
||||||
|
#define __msan_get_origin(void *a) ((u32)-1)
|
||||||
|
#define __msan_get_track_origins() (0)
|
||||||
|
#define __msan_get_umr_origin() ((u32)-1)
|
||||||
|
#define __msan_unpoison(void *a, uptr size)
|
||||||
|
#define __msan_poison(void *a, uptr size)
|
||||||
|
#define __msan_partial_poison(void* data, void* shadow, uptr size)
|
||||||
|
#define __msan_test_shadow(const void *x, uptr size) ((sptr)-1)
|
||||||
|
#define __msan_set_exit_code(int exit_code)
|
||||||
|
#define __msan_set_expect_umr(int expect_umr)
|
||||||
|
#define __msan_print_shadow(const void *x, uptr size)
|
||||||
|
#define __msan_print_param_shadow()
|
||||||
|
#define __msan_has_dynamic_component() (0)
|
||||||
|
#define __msan_allocated_memory(data, size)
|
||||||
|
|
||||||
|
#endif // __has_feature(memory_sanitizer)
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
} // extern "C"
|
} // extern "C"
|
||||||
|
|
|
@ -306,8 +306,6 @@ int __msan_set_poison_in_malloc(int do_poison) {
|
||||||
return old;
|
return old;
|
||||||
}
|
}
|
||||||
|
|
||||||
void __msan_break_optimization(void *x) { }
|
|
||||||
|
|
||||||
int __msan_has_dynamic_component() {
|
int __msan_has_dynamic_component() {
|
||||||
return msan_running_under_dr;
|
return msan_running_under_dr;
|
||||||
}
|
}
|
||||||
|
@ -413,6 +411,6 @@ u32 __msan_get_origin(void *a) {
|
||||||
return *(u32*)origin_ptr;
|
return *(u32*)origin_ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 __msan_get_origin_tls() {
|
u32 __msan_get_umr_origin() {
|
||||||
return __msan_origin_tls;
|
return __msan_origin_tls;
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
|
|
||||||
#include "sanitizer_common/sanitizer_internal_defs.h"
|
#include "sanitizer_common/sanitizer_internal_defs.h"
|
||||||
#include "sanitizer_common/sanitizer_stacktrace.h"
|
#include "sanitizer_common/sanitizer_stacktrace.h"
|
||||||
#include "sanitizer/msan_interface.h"
|
#include "msan_interface_internal.h"
|
||||||
#include "msan_flags.h"
|
#include "msan_flags.h"
|
||||||
|
|
||||||
#define MEM_TO_SHADOW(mem) (((uptr)mem) & ~0x400000000000ULL)
|
#define MEM_TO_SHADOW(mem) (((uptr)mem) & ~0x400000000000ULL)
|
||||||
|
|
|
@ -0,0 +1,120 @@
|
||||||
|
//===-- msan_interface_internal.h -------------------------------*- C++ -*-===//
|
||||||
|
//
|
||||||
|
// The LLVM Compiler Infrastructure
|
||||||
|
//
|
||||||
|
// This file is distributed under the University of Illinois Open Source
|
||||||
|
// License. See LICENSE.TXT for details.
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
//
|
||||||
|
// This file is a part of MemorySanitizer.
|
||||||
|
//
|
||||||
|
// Private MSan interface header.
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
#ifndef MSAN_INTERFACE_INTERNAL_H
|
||||||
|
#define MSAN_INTERFACE_INTERNAL_H
|
||||||
|
|
||||||
|
#include <sanitizer/common_interface_defs.h>
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
|
||||||
|
// FIXME: document all interface functions.
|
||||||
|
|
||||||
|
SANITIZER_INTERFACE_ATTRIBUTE
|
||||||
|
int __msan_get_track_origins();
|
||||||
|
|
||||||
|
SANITIZER_INTERFACE_ATTRIBUTE
|
||||||
|
void __msan_init();
|
||||||
|
|
||||||
|
// Print a warning and maybe return.
|
||||||
|
// This function can die based on flags()->exit_code.
|
||||||
|
SANITIZER_INTERFACE_ATTRIBUTE
|
||||||
|
void __msan_warning();
|
||||||
|
|
||||||
|
// Print a warning and die.
|
||||||
|
// Intrumentation inserts calls to this function when building in "fast" mode
|
||||||
|
// (i.e. -mllvm -msan-keep-going)
|
||||||
|
SANITIZER_INTERFACE_ATTRIBUTE __attribute__((noreturn))
|
||||||
|
void __msan_warning_noreturn();
|
||||||
|
|
||||||
|
SANITIZER_INTERFACE_ATTRIBUTE
|
||||||
|
void __msan_unpoison(void *a, uptr size);
|
||||||
|
SANITIZER_INTERFACE_ATTRIBUTE
|
||||||
|
void __msan_clear_and_unpoison(void *a, uptr size);
|
||||||
|
SANITIZER_INTERFACE_ATTRIBUTE
|
||||||
|
void* __msan_memcpy(void *dst, const void *src, uptr size);
|
||||||
|
SANITIZER_INTERFACE_ATTRIBUTE
|
||||||
|
void* __msan_memset(void *s, int c, uptr n);
|
||||||
|
SANITIZER_INTERFACE_ATTRIBUTE
|
||||||
|
void* __msan_memmove(void* dest, const void* src, uptr n);
|
||||||
|
SANITIZER_INTERFACE_ATTRIBUTE
|
||||||
|
void __msan_copy_poison(void *dst, const void *src, uptr size);
|
||||||
|
SANITIZER_INTERFACE_ATTRIBUTE
|
||||||
|
void __msan_copy_origin(void *dst, const void *src, uptr size);
|
||||||
|
SANITIZER_INTERFACE_ATTRIBUTE
|
||||||
|
void __msan_move_poison(void *dst, const void *src, uptr size);
|
||||||
|
SANITIZER_INTERFACE_ATTRIBUTE
|
||||||
|
void __msan_poison(void *a, uptr size);
|
||||||
|
SANITIZER_INTERFACE_ATTRIBUTE
|
||||||
|
void __msan_poison_stack(void *a, uptr size);
|
||||||
|
|
||||||
|
// Copy size bytes from src to dst and unpoison the result.
|
||||||
|
// Useful to implement unsafe loads.
|
||||||
|
SANITIZER_INTERFACE_ATTRIBUTE
|
||||||
|
void __msan_load_unpoisoned(void *src, uptr size, void *dst);
|
||||||
|
|
||||||
|
// Returns the offset of the first (at least partially) poisoned byte,
|
||||||
|
// or -1 if the whole range is good.
|
||||||
|
SANITIZER_INTERFACE_ATTRIBUTE
|
||||||
|
sptr __msan_test_shadow(const void *x, uptr size);
|
||||||
|
|
||||||
|
SANITIZER_INTERFACE_ATTRIBUTE
|
||||||
|
void __msan_set_origin(void *a, uptr size, u32 origin);
|
||||||
|
SANITIZER_INTERFACE_ATTRIBUTE
|
||||||
|
void __msan_set_alloca_origin(void *a, uptr size, const char *descr);
|
||||||
|
SANITIZER_INTERFACE_ATTRIBUTE
|
||||||
|
u32 __msan_get_origin(void *a);
|
||||||
|
|
||||||
|
SANITIZER_INTERFACE_ATTRIBUTE
|
||||||
|
void __msan_clear_on_return();
|
||||||
|
|
||||||
|
// Default: -1 (don't exit on error).
|
||||||
|
SANITIZER_INTERFACE_ATTRIBUTE
|
||||||
|
void __msan_set_exit_code(int exit_code);
|
||||||
|
|
||||||
|
SANITIZER_INTERFACE_ATTRIBUTE
|
||||||
|
int __msan_set_poison_in_malloc(int do_poison);
|
||||||
|
|
||||||
|
// For testing.
|
||||||
|
SANITIZER_INTERFACE_ATTRIBUTE
|
||||||
|
void __msan_set_expect_umr(int expect_umr);
|
||||||
|
SANITIZER_INTERFACE_ATTRIBUTE
|
||||||
|
void __msan_print_shadow(const void *x, uptr size);
|
||||||
|
SANITIZER_INTERFACE_ATTRIBUTE
|
||||||
|
void __msan_print_param_shadow();
|
||||||
|
SANITIZER_INTERFACE_ATTRIBUTE
|
||||||
|
int __msan_has_dynamic_component();
|
||||||
|
|
||||||
|
// Returns x such that %fs:x is the first byte of __msan_retval_tls.
|
||||||
|
SANITIZER_INTERFACE_ATTRIBUTE
|
||||||
|
int __msan_get_retval_tls_offset();
|
||||||
|
SANITIZER_INTERFACE_ATTRIBUTE
|
||||||
|
int __msan_get_param_tls_offset();
|
||||||
|
|
||||||
|
// For testing.
|
||||||
|
SANITIZER_INTERFACE_ATTRIBUTE
|
||||||
|
u32 __msan_get_umr_origin();
|
||||||
|
SANITIZER_INTERFACE_ATTRIBUTE
|
||||||
|
const char *__msan_get_origin_descr_if_stack(u32 id);
|
||||||
|
SANITIZER_INTERFACE_ATTRIBUTE
|
||||||
|
void __msan_partial_poison(void* data, void* shadow, uptr size);
|
||||||
|
|
||||||
|
// Tell MSan about newly allocated memory (ex.: custom allocator).
|
||||||
|
// Memory will be marked uninitialized, with origin at the call site.
|
||||||
|
SANITIZER_INTERFACE_ATTRIBUTE
|
||||||
|
void __msan_allocated_memory(void* data, uptr size);
|
||||||
|
|
||||||
|
} // extern "C"
|
||||||
|
|
||||||
|
#endif // MSAN_INTERFACE_INTERNAL_H
|
|
@ -32,7 +32,10 @@ set(MSAN_LIBCXX_LINK_FLAGS
|
||||||
|
|
||||||
# Unittest sources and build flags.
|
# Unittest sources and build flags.
|
||||||
set(MSAN_UNITTEST_SOURCE msan_test.cc)
|
set(MSAN_UNITTEST_SOURCE msan_test.cc)
|
||||||
set(MSAN_UNITTEST_HEADERS msandr_test_so.h)
|
set(MSAN_UNITTEST_HEADERS
|
||||||
|
msandr_test_so.h
|
||||||
|
../../../include/sanitizer/msan_interface.h
|
||||||
|
)
|
||||||
set(MSANDR_UNITTEST_SOURCE msandr_test_so.cc)
|
set(MSANDR_UNITTEST_SOURCE msandr_test_so.cc)
|
||||||
set(MSAN_UNITTEST_COMMON_CFLAGS
|
set(MSAN_UNITTEST_COMMON_CFLAGS
|
||||||
-I${MSAN_LIBCXX_PATH}/include
|
-I${MSAN_LIBCXX_PATH}/include
|
||||||
|
|
|
@ -74,7 +74,7 @@ static bool TrackingOrigins() {
|
||||||
action; \
|
action; \
|
||||||
__msan_set_expect_umr(0); \
|
__msan_set_expect_umr(0); \
|
||||||
if (TrackingOrigins()) \
|
if (TrackingOrigins()) \
|
||||||
EXPECT_EQ(origin, __msan_get_origin_tls()); \
|
EXPECT_EQ(origin, __msan_get_umr_origin()); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define EXPECT_UMR_S(action, stack_origin) \
|
#define EXPECT_UMR_S(action, stack_origin) \
|
||||||
|
@ -82,7 +82,7 @@ static bool TrackingOrigins() {
|
||||||
__msan_set_expect_umr(1); \
|
__msan_set_expect_umr(1); \
|
||||||
action; \
|
action; \
|
||||||
__msan_set_expect_umr(0); \
|
__msan_set_expect_umr(0); \
|
||||||
u32 id = __msan_get_origin_tls(); \
|
u32 id = __msan_get_umr_origin(); \
|
||||||
const char *str = __msan_get_origin_descr_if_stack(id); \
|
const char *str = __msan_get_origin_descr_if_stack(id); \
|
||||||
if (!str || strcmp(str, stack_origin)) { \
|
if (!str || strcmp(str, stack_origin)) { \
|
||||||
fprintf(stderr, "EXPECT_POISONED_S: id=%u %s, %s", \
|
fprintf(stderr, "EXPECT_POISONED_S: id=%u %s, %s", \
|
||||||
|
@ -167,6 +167,14 @@ static volatile int g_1 = 1;
|
||||||
S4 a_s4[100];
|
S4 a_s4[100];
|
||||||
S8 a_s8[100];
|
S8 a_s8[100];
|
||||||
|
|
||||||
|
// Check that malloc poisons memory.
|
||||||
|
// A lot of tests below depend on this.
|
||||||
|
TEST(MemorySanitizerSanity, PoisonInMalloc) {
|
||||||
|
int *x = (int*)malloc(sizeof(int));
|
||||||
|
EXPECT_POISONED(*x);
|
||||||
|
free(x);
|
||||||
|
}
|
||||||
|
|
||||||
TEST(MemorySanitizer, NegativeTest1) {
|
TEST(MemorySanitizer, NegativeTest1) {
|
||||||
S4 *x = GetPoisoned<S4>();
|
S4 *x = GetPoisoned<S4>();
|
||||||
if (g_one)
|
if (g_one)
|
||||||
|
@ -221,7 +229,7 @@ TEST(MemorySanitizer, Phi1) {
|
||||||
if (g_one) {
|
if (g_one) {
|
||||||
c = *GetPoisoned<S4>();
|
c = *GetPoisoned<S4>();
|
||||||
} else {
|
} else {
|
||||||
__msan_break_optimization(0);
|
break_optimization(0);
|
||||||
c = 0;
|
c = 0;
|
||||||
}
|
}
|
||||||
EXPECT_POISONED(c);
|
EXPECT_POISONED(c);
|
||||||
|
@ -393,14 +401,14 @@ NOINLINE static int GetPoisonedZero() {
|
||||||
TEST(MemorySanitizer, LoadFromDirtyAddress) {
|
TEST(MemorySanitizer, LoadFromDirtyAddress) {
|
||||||
int *a = new int;
|
int *a = new int;
|
||||||
*a = 0;
|
*a = 0;
|
||||||
EXPECT_UMR(__msan_break_optimization((void*)(U8)a[GetPoisonedZero()]));
|
EXPECT_UMR(break_optimization((void*)(U8)a[GetPoisonedZero()]));
|
||||||
delete a;
|
delete a;
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(MemorySanitizer, StoreToDirtyAddress) {
|
TEST(MemorySanitizer, StoreToDirtyAddress) {
|
||||||
int *a = new int;
|
int *a = new int;
|
||||||
EXPECT_UMR(a[GetPoisonedZero()] = 0);
|
EXPECT_UMR(a[GetPoisonedZero()] = 0);
|
||||||
__msan_break_optimization(a);
|
break_optimization(a);
|
||||||
delete a;
|
delete a;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -412,12 +420,12 @@ NOINLINE void StackTestFunc() {
|
||||||
S2 ok2 = 1;
|
S2 ok2 = 1;
|
||||||
S1 p1;
|
S1 p1;
|
||||||
S1 ok1 = 1;
|
S1 ok1 = 1;
|
||||||
__msan_break_optimization(&p4);
|
break_optimization(&p4);
|
||||||
__msan_break_optimization(&ok4);
|
break_optimization(&ok4);
|
||||||
__msan_break_optimization(&p2);
|
break_optimization(&p2);
|
||||||
__msan_break_optimization(&ok2);
|
break_optimization(&ok2);
|
||||||
__msan_break_optimization(&p1);
|
break_optimization(&p1);
|
||||||
__msan_break_optimization(&ok1);
|
break_optimization(&ok1);
|
||||||
|
|
||||||
EXPECT_POISONED(p4);
|
EXPECT_POISONED(p4);
|
||||||
EXPECT_POISONED(p2);
|
EXPECT_POISONED(p2);
|
||||||
|
@ -433,7 +441,7 @@ TEST(MemorySanitizer, StackTest) {
|
||||||
|
|
||||||
NOINLINE void StackStressFunc() {
|
NOINLINE void StackStressFunc() {
|
||||||
int foo[10000];
|
int foo[10000];
|
||||||
__msan_break_optimization(foo);
|
break_optimization(foo);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(MemorySanitizer, DISABLED_StackStressTest) {
|
TEST(MemorySanitizer, DISABLED_StackStressTest) {
|
||||||
|
@ -445,7 +453,7 @@ template<class T>
|
||||||
void TestFloatingPoint() {
|
void TestFloatingPoint() {
|
||||||
static volatile T v;
|
static volatile T v;
|
||||||
static T g[100];
|
static T g[100];
|
||||||
__msan_break_optimization(&g);
|
break_optimization(&g);
|
||||||
T *x = GetPoisoned<T>();
|
T *x = GetPoisoned<T>();
|
||||||
T *y = GetPoisoned<T>(1);
|
T *y = GetPoisoned<T>(1);
|
||||||
EXPECT_POISONED(*x);
|
EXPECT_POISONED(*x);
|
||||||
|
@ -723,7 +731,7 @@ TEST(MemorySanitizer, strtold) {
|
||||||
|
|
||||||
TEST(MemorySanitizer, sprintf) { // NOLINT
|
TEST(MemorySanitizer, sprintf) { // NOLINT
|
||||||
char buff[10];
|
char buff[10];
|
||||||
__msan_break_optimization(buff);
|
break_optimization(buff);
|
||||||
EXPECT_POISONED(buff[0]);
|
EXPECT_POISONED(buff[0]);
|
||||||
int res = sprintf(buff, "%d", 1234567); // NOLINT
|
int res = sprintf(buff, "%d", 1234567); // NOLINT
|
||||||
assert(res == 7);
|
assert(res == 7);
|
||||||
|
@ -737,7 +745,7 @@ TEST(MemorySanitizer, sprintf) { // NOLINT
|
||||||
|
|
||||||
TEST(MemorySanitizer, snprintf) {
|
TEST(MemorySanitizer, snprintf) {
|
||||||
char buff[10];
|
char buff[10];
|
||||||
__msan_break_optimization(buff);
|
break_optimization(buff);
|
||||||
EXPECT_POISONED(buff[0]);
|
EXPECT_POISONED(buff[0]);
|
||||||
int res = snprintf(buff, sizeof(buff), "%d", 1234567);
|
int res = snprintf(buff, sizeof(buff), "%d", 1234567);
|
||||||
assert(res == 7);
|
assert(res == 7);
|
||||||
|
@ -752,7 +760,7 @@ TEST(MemorySanitizer, snprintf) {
|
||||||
TEST(MemorySanitizer, swprintf) {
|
TEST(MemorySanitizer, swprintf) {
|
||||||
wchar_t buff[10];
|
wchar_t buff[10];
|
||||||
assert(sizeof(wchar_t) == 4);
|
assert(sizeof(wchar_t) == 4);
|
||||||
__msan_break_optimization(buff);
|
break_optimization(buff);
|
||||||
EXPECT_POISONED(buff[0]);
|
EXPECT_POISONED(buff[0]);
|
||||||
int res = swprintf(buff, 9, L"%d", 1234567);
|
int res = swprintf(buff, 9, L"%d", 1234567);
|
||||||
assert(res == 7);
|
assert(res == 7);
|
||||||
|
@ -777,8 +785,8 @@ TEST(MemorySanitizer, wcstombs) {
|
||||||
TEST(MemorySanitizer, gettimeofday) {
|
TEST(MemorySanitizer, gettimeofday) {
|
||||||
struct timeval tv;
|
struct timeval tv;
|
||||||
struct timezone tz;
|
struct timezone tz;
|
||||||
__msan_break_optimization(&tv);
|
break_optimization(&tv);
|
||||||
__msan_break_optimization(&tz);
|
break_optimization(&tz);
|
||||||
assert(sizeof(tv) == 16);
|
assert(sizeof(tv) == 16);
|
||||||
assert(sizeof(tz) == 8);
|
assert(sizeof(tz) == 8);
|
||||||
EXPECT_POISONED(tv.tv_sec);
|
EXPECT_POISONED(tv.tv_sec);
|
||||||
|
@ -815,8 +823,8 @@ TEST(MemorySanitizer, mmap) {
|
||||||
// FIXME: check why msandr does nt handle fcvt.
|
// FIXME: check why msandr does nt handle fcvt.
|
||||||
TEST(MemorySanitizer, fcvt) {
|
TEST(MemorySanitizer, fcvt) {
|
||||||
int a, b;
|
int a, b;
|
||||||
__msan_break_optimization(&a);
|
break_optimization(&a);
|
||||||
__msan_break_optimization(&b);
|
break_optimization(&b);
|
||||||
EXPECT_POISONED(a);
|
EXPECT_POISONED(a);
|
||||||
EXPECT_POISONED(b);
|
EXPECT_POISONED(b);
|
||||||
char *str = fcvt(12345.6789, 10, &a, &b);
|
char *str = fcvt(12345.6789, 10, &a, &b);
|
||||||
|
@ -824,20 +832,12 @@ TEST(MemorySanitizer, fcvt) {
|
||||||
EXPECT_NOT_POISONED(b);
|
EXPECT_NOT_POISONED(b);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(MemorySanitizer, LoadUnpoisoned) {
|
|
||||||
S8 s = *GetPoisoned<S8>();
|
|
||||||
EXPECT_POISONED(s);
|
|
||||||
S8 safe = *GetPoisoned<S8>();
|
|
||||||
__msan_load_unpoisoned(&s, sizeof(s), &safe);
|
|
||||||
EXPECT_NOT_POISONED(safe);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct StructWithDtor {
|
struct StructWithDtor {
|
||||||
~StructWithDtor();
|
~StructWithDtor();
|
||||||
};
|
};
|
||||||
|
|
||||||
NOINLINE StructWithDtor::~StructWithDtor() {
|
NOINLINE StructWithDtor::~StructWithDtor() {
|
||||||
__msan_break_optimization(0);
|
break_optimization(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(MemorySanitizer, Invoke) {
|
TEST(MemorySanitizer, Invoke) {
|
||||||
|
@ -1106,7 +1106,7 @@ NOINLINE StructWithHole ReturnStructWithHole() {
|
||||||
|
|
||||||
TEST(MemorySanitizer, StructWithHole) {
|
TEST(MemorySanitizer, StructWithHole) {
|
||||||
StructWithHole a = ReturnStructWithHole();
|
StructWithHole a = ReturnStructWithHole();
|
||||||
__msan_break_optimization(&a);
|
break_optimization(&a);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
|
@ -1518,7 +1518,7 @@ void BinaryOpOriginTest(BinaryOp op) {
|
||||||
// y is poisoned, x is not.
|
// y is poisoned, x is not.
|
||||||
*x = 10101;
|
*x = 10101;
|
||||||
*y = *GetPoisonedO<T>(1, oy);
|
*y = *GetPoisonedO<T>(1, oy);
|
||||||
__msan_break_optimization(x);
|
break_optimization(x);
|
||||||
__msan_set_origin(z, sizeof(*z), 0);
|
__msan_set_origin(z, sizeof(*z), 0);
|
||||||
*z = op(*x, *y);
|
*z = op(*x, *y);
|
||||||
EXPECT_POISONED_O(*z, oy);
|
EXPECT_POISONED_O(*z, oy);
|
||||||
|
@ -1527,7 +1527,7 @@ void BinaryOpOriginTest(BinaryOp op) {
|
||||||
// x is poisoned, y is not.
|
// x is poisoned, y is not.
|
||||||
*x = *GetPoisonedO<T>(0, ox);
|
*x = *GetPoisonedO<T>(0, ox);
|
||||||
*y = 10101010;
|
*y = 10101010;
|
||||||
__msan_break_optimization(y);
|
break_optimization(y);
|
||||||
__msan_set_origin(z, sizeof(*z), 0);
|
__msan_set_origin(z, sizeof(*z), 0);
|
||||||
*z = op(*x, *y);
|
*z = op(*x, *y);
|
||||||
EXPECT_POISONED_O(*z, ox);
|
EXPECT_POISONED_O(*z, ox);
|
||||||
|
@ -1645,7 +1645,7 @@ TEST(MemorySanitizerOrigins, Select) {
|
||||||
EXPECT_NOT_POISONED(g_one ? 1 : *GetPoisonedO<S4>(0, __LINE__));
|
EXPECT_NOT_POISONED(g_one ? 1 : *GetPoisonedO<S4>(0, __LINE__));
|
||||||
EXPECT_POISONED_O(*GetPoisonedO<S4>(0, __LINE__), __LINE__);
|
EXPECT_POISONED_O(*GetPoisonedO<S4>(0, __LINE__), __LINE__);
|
||||||
S4 x;
|
S4 x;
|
||||||
__msan_break_optimization(&x);
|
break_optimization(&x);
|
||||||
x = g_1 ? *GetPoisonedO<S4>(0, __LINE__) : 0;
|
x = g_1 ? *GetPoisonedO<S4>(0, __LINE__) : 0;
|
||||||
|
|
||||||
EXPECT_POISONED_O(g_1 ? *GetPoisonedO<S4>(0, __LINE__) : 1, __LINE__);
|
EXPECT_POISONED_O(g_1 ? *GetPoisonedO<S4>(0, __LINE__) : 1, __LINE__);
|
||||||
|
@ -1655,7 +1655,7 @@ TEST(MemorySanitizerOrigins, Select) {
|
||||||
extern "C"
|
extern "C"
|
||||||
NOINLINE char AllocaTO() {
|
NOINLINE char AllocaTO() {
|
||||||
int ar[100];
|
int ar[100];
|
||||||
__msan_break_optimization(ar);
|
break_optimization(ar);
|
||||||
return ar[10];
|
return ar[10];
|
||||||
// fprintf(stderr, "Descr: %s\n",
|
// fprintf(stderr, "Descr: %s\n",
|
||||||
// __msan_get_origin_descr_if_stack(__msan_get_origin_tls()));
|
// __msan_get_origin_descr_if_stack(__msan_get_origin_tls()));
|
||||||
|
@ -1677,7 +1677,7 @@ TEST(MemorySanitizerOrigins, DISABLED_AllocaDeath) {
|
||||||
|
|
||||||
NOINLINE int RetvalOriginTest(u32 origin) {
|
NOINLINE int RetvalOriginTest(u32 origin) {
|
||||||
int *a = new int;
|
int *a = new int;
|
||||||
__msan_break_optimization(a);
|
break_optimization(a);
|
||||||
__msan_set_origin(a, sizeof(*a), origin);
|
__msan_set_origin(a, sizeof(*a), origin);
|
||||||
int res = *a;
|
int res = *a;
|
||||||
delete a;
|
delete a;
|
||||||
|
@ -1697,7 +1697,7 @@ TEST(MemorySanitizerOrigins, Param) {
|
||||||
if (!TrackingOrigins()) return;
|
if (!TrackingOrigins()) return;
|
||||||
int *a = new int;
|
int *a = new int;
|
||||||
u32 origin = __LINE__;
|
u32 origin = __LINE__;
|
||||||
__msan_break_optimization(a);
|
break_optimization(a);
|
||||||
__msan_set_origin(a, sizeof(*a), origin);
|
__msan_set_origin(a, sizeof(*a), origin);
|
||||||
ParamOriginTest(*a, origin);
|
ParamOriginTest(*a, origin);
|
||||||
delete a;
|
delete a;
|
||||||
|
@ -1711,7 +1711,7 @@ TEST(MemorySanitizerOrigins, Invoke) {
|
||||||
|
|
||||||
TEST(MemorySanitizerOrigins, strlen) {
|
TEST(MemorySanitizerOrigins, strlen) {
|
||||||
S8 alignment;
|
S8 alignment;
|
||||||
__msan_break_optimization(&alignment);
|
break_optimization(&alignment);
|
||||||
char x[4] = {'a', 'b', 0, 0};
|
char x[4] = {'a', 'b', 0, 0};
|
||||||
__msan_poison(&x[2], 1);
|
__msan_poison(&x[2], 1);
|
||||||
u32 origin = __LINE__;
|
u32 origin = __LINE__;
|
||||||
|
@ -1745,8 +1745,8 @@ NOINLINE void RecursiveMalloc(int depth) {
|
||||||
printf("RecursiveMalloc: %d\n", count);
|
printf("RecursiveMalloc: %d\n", count);
|
||||||
int *x1 = new int;
|
int *x1 = new int;
|
||||||
int *x2 = new int;
|
int *x2 = new int;
|
||||||
__msan_break_optimization(x1);
|
break_optimization(x1);
|
||||||
__msan_break_optimization(x2);
|
break_optimization(x2);
|
||||||
if (depth > 0) {
|
if (depth > 0) {
|
||||||
RecursiveMalloc(depth-1);
|
RecursiveMalloc(depth-1);
|
||||||
RecursiveMalloc(depth-1);
|
RecursiveMalloc(depth-1);
|
||||||
|
@ -1768,7 +1768,6 @@ TEST(MemorySanitizerStress, DISABLED_MallocStackTrace) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char **argv) {
|
int main(int argc, char **argv) {
|
||||||
__msan_set_poison_in_malloc(1);
|
|
||||||
testing::InitGoogleTest(&argc, argv);
|
testing::InitGoogleTest(&argc, argv);
|
||||||
int res = RUN_ALL_TESTS();
|
int res = RUN_ALL_TESTS();
|
||||||
return res;
|
return res;
|
||||||
|
|
|
@ -34,3 +34,5 @@ int dso_stack_store(void (*fn)(int*, int*), int x) {
|
||||||
fn(&x, &y);
|
fn(&x, &y);
|
||||||
return y;
|
return y;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void break_optimization(void *x) {}
|
||||||
|
|
|
@ -19,5 +19,6 @@ void dso_memfill(char* s, unsigned n);
|
||||||
int dso_callfn(int (*fn)(void));
|
int dso_callfn(int (*fn)(void));
|
||||||
int dso_callfn1(int (*fn)(long long, long long, long long)); //NOLINT
|
int dso_callfn1(int (*fn)(long long, long long, long long)); //NOLINT
|
||||||
int dso_stack_store(void (*fn)(int*, int*), int x);
|
int dso_stack_store(void (*fn)(int*, int*), int x);
|
||||||
|
void break_optimization(void *x);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue