forked from OSchip/llvm-project
[ASan] Nuke output_tests/ in favor of lit_tests/. Stop using Makefile.old.
llvm-svn: 163294
This commit is contained in:
parent
f3e4aa8cdd
commit
ac87a5bddc
|
@ -4,22 +4,26 @@ This directory contains sources of the AddressSanitizer (asan) run-time library.
|
|||
We are in the process of integrating AddressSanitizer with LLVM, stay tuned.
|
||||
|
||||
Directory structre:
|
||||
|
||||
README.txt : This file.
|
||||
Makefile.mk : Currently a stub for a proper makefile. not usable.
|
||||
Makefile.old : Old out-of-tree makefile, the only usable one so far.
|
||||
Makefile.mk : File for make-based build.
|
||||
CMakeLists.txt : File for cmake-based build.
|
||||
asan_*.{cc,h} : Sources of the asan run-time lirbary.
|
||||
mach_override/* : Utility to override functions on Darwin (MIT License).
|
||||
scripts/* : Helper scripts.
|
||||
tests/* : ASan unit tests.
|
||||
lit_tests/* : ASan output tests.
|
||||
|
||||
Temporary build instructions (verified on linux):
|
||||
Also ASan runtime needs the following libraries:
|
||||
lib/interception/ : Machinery used to intercept function calls.
|
||||
lib/sanitizer_common/ : Code shared between ASan and TSan.
|
||||
|
||||
cd lib/asan
|
||||
make -f Makefile.old get_third_party # gets googletest
|
||||
make -f Makefile.old test -j 8 CLANG_BUILD=/path/to/Release+Asserts
|
||||
# Optional:
|
||||
# make -f Makefile.old install # installs clang and rt to lib/asan_clang_linux
|
||||
Currently ASan runtime can be built by both make and cmake build systems.
|
||||
(see compiler-rt/make and files Makefile.mk for make-based build and
|
||||
files CMakeLists.txt for cmake-based build).
|
||||
|
||||
For more info see http://code.google.com/p/address-sanitizer/
|
||||
ASan unit and output tests work only with cmake. You may run this
|
||||
command from the root of your cmake build tree:
|
||||
|
||||
make check-asan
|
||||
|
||||
For more instructions see:
|
||||
http://code.google.com/p/address-sanitizer/wiki/HowToBuild
|
||||
|
|
|
@ -1,34 +0,0 @@
|
|||
#ifdef __linux__
|
||||
#include <stdio.h>
|
||||
#include <sched.h>
|
||||
#include <sys/syscall.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
#include <unistd.h>
|
||||
|
||||
int Child(void *arg) {
|
||||
char x[32] = {0}; // Stack gets poisoned.
|
||||
printf("Child: %p\n", x);
|
||||
_exit(1); // NoReturn, stack will remain unpoisoned unless we do something.
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
const int kStackSize = 1 << 20;
|
||||
char child_stack[kStackSize + 1];
|
||||
char *sp = child_stack + kStackSize; // Stack grows down.
|
||||
printf("Parent: %p\n", sp);
|
||||
pid_t clone_pid = clone(Child, sp, CLONE_FILES | CLONE_VM, NULL, 0, 0, 0);
|
||||
waitpid(clone_pid, NULL, 0);
|
||||
for (int i = 0; i < kStackSize; i++)
|
||||
child_stack[i] = i;
|
||||
int ret = child_stack[argc - 1];
|
||||
printf("PASSED\n");
|
||||
return ret;
|
||||
}
|
||||
#else // not __linux__
|
||||
#include <stdio.h>
|
||||
int main() {
|
||||
printf("PASSED\n");
|
||||
// Check-Common: PASSED
|
||||
}
|
||||
#endif
|
|
@ -1,15 +0,0 @@
|
|||
// Check-Common: AddressSanitizer global-buffer-overflow
|
||||
int global[10];
|
||||
// Check-Common: {{#0.*call4}}
|
||||
void __attribute__((noinline)) call4(int i) { global[i+10]++; }
|
||||
// Check-Common: {{#1.*call3}}
|
||||
void __attribute__((noinline)) call3(int i) { call4(i); }
|
||||
// Check-Common: {{#2.*call2}}
|
||||
void __attribute__((noinline)) call2(int i) { call3(i); }
|
||||
// Check-Common: {{#3.*call1}}
|
||||
void __attribute__((noinline)) call1(int i) { call2(i); }
|
||||
// Check-Common: {{#4.*main}}
|
||||
int main(int argc, char **argv) {
|
||||
call1(argc);
|
||||
return global[0];
|
||||
}
|
|
@ -1,12 +0,0 @@
|
|||
const char *kAsanDefaultOptions="verbosity=1 foo=bar";
|
||||
|
||||
extern "C"
|
||||
__attribute__((no_address_safety_analysis))
|
||||
const char *__asan_default_options() {
|
||||
return kAsanDefaultOptions;
|
||||
}
|
||||
|
||||
int main() {
|
||||
// Check-Common: foo=bar
|
||||
return 0;
|
||||
}
|
|
@ -1,33 +0,0 @@
|
|||
//===----------- dlclose-test-so.cc -----------------------------*- 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 AddressSanitizer, an address sanity checker.
|
||||
//
|
||||
// Regression test for
|
||||
// http://code.google.com/p/address-sanitizer/issues/detail?id=19
|
||||
//===----------------------------------------------------------------------===//
|
||||
#include <stdio.h>
|
||||
|
||||
static int pad1;
|
||||
static int static_var;
|
||||
static int pad2;
|
||||
|
||||
extern "C"
|
||||
int *get_address_of_static_var() {
|
||||
return &static_var;
|
||||
}
|
||||
|
||||
__attribute__((constructor))
|
||||
void at_dlopen() {
|
||||
printf("%s: I am being dlopened\n", __FILE__);
|
||||
}
|
||||
__attribute__((destructor))
|
||||
void at_dlclose() {
|
||||
printf("%s: I am being dlclosed\n", __FILE__);
|
||||
}
|
|
@ -1,74 +0,0 @@
|
|||
//===----------- dlclose-test.cc --------------------------------*- 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 AddressSanitizer, an address sanity checker.
|
||||
//
|
||||
// Regression test for
|
||||
// http://code.google.com/p/address-sanitizer/issues/detail?id=19
|
||||
// Bug description:
|
||||
// 1. application dlopens foo.so
|
||||
// 2. asan registers all globals from foo.so
|
||||
// 3. application dlcloses foo.so
|
||||
// 4. application mmaps some memory to the location where foo.so was before
|
||||
// 5. application starts using this mmaped memory, but asan still thinks there
|
||||
// are globals.
|
||||
// 6. BOOM
|
||||
//===----------------------------------------------------------------------===//
|
||||
#include <assert.h>
|
||||
#include <dlfcn.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/mman.h>
|
||||
|
||||
#include <string>
|
||||
|
||||
using std::string;
|
||||
|
||||
static const int kPageSize = 4096;
|
||||
|
||||
typedef int *(fun_t)();
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
string path = string(argv[0]) + "-so.so";
|
||||
printf("opening %s ... \n", path.c_str());
|
||||
void *lib = dlopen(path.c_str(), RTLD_NOW);
|
||||
if (!lib) {
|
||||
printf("error in dlopen(): %s\n", dlerror());
|
||||
return 1;
|
||||
}
|
||||
fun_t *get = (fun_t*)dlsym(lib, "get_address_of_static_var");
|
||||
if (!get) {
|
||||
printf("failed dlsym\n");
|
||||
return 1;
|
||||
}
|
||||
int *addr = get();
|
||||
assert(((size_t)addr % 32) == 0); // should be 32-byte aligned.
|
||||
printf("addr: %p\n", addr);
|
||||
addr[0] = 1; // make sure we can write there.
|
||||
|
||||
// Now dlclose the shared library.
|
||||
printf("attempting to dlclose\n");
|
||||
if (dlclose(lib)) {
|
||||
printf("failed to dlclose\n");
|
||||
return 1;
|
||||
}
|
||||
// Now, the page where 'addr' is unmapped. Map it.
|
||||
size_t page_beg = ((size_t)addr) & ~(kPageSize - 1);
|
||||
void *res = mmap((void*)(page_beg), kPageSize,
|
||||
PROT_READ | PROT_WRITE,
|
||||
MAP_PRIVATE | MAP_ANON | MAP_FIXED | MAP_NORESERVE, 0, 0);
|
||||
if (res == (char*)-1L) {
|
||||
printf("failed to mmap\n");
|
||||
return 1;
|
||||
}
|
||||
addr[1] = 2; // BOOM (if the bug is not fixed).
|
||||
printf("PASS\n");
|
||||
// Check-Common: PASS
|
||||
return 0;
|
||||
}
|
|
@ -1,16 +0,0 @@
|
|||
#include <string.h>
|
||||
int main(int argc, char **argv) {
|
||||
static char XXX[10];
|
||||
static char YYY[10];
|
||||
static char ZZZ[10];
|
||||
memset(XXX, 0, 10);
|
||||
memset(YYY, 0, 10);
|
||||
memset(ZZZ, 0, 10);
|
||||
int res = YYY[argc * 10]; // BOOOM
|
||||
// Check-Common: {{READ of size 1 at 0x.* thread T0}}
|
||||
// Check-Common: {{ #0 0x.* in main .*global-overflow.cc:9}}
|
||||
// Check-Common: {{0x.* is located 0 bytes to the right of global variable}}
|
||||
// Check-Common: {{.*YYY.* of size 10}}
|
||||
res += XXX[argc] + ZZZ[argc];
|
||||
return res;
|
||||
}
|
|
@ -1,22 +0,0 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
int main(int argc, char **argv) {
|
||||
char *x = (char*)malloc(10 * sizeof(char));
|
||||
memset(x, 0, 10);
|
||||
int res = x[argc * 10]; // BOOOM
|
||||
free(x);
|
||||
return res;
|
||||
}
|
||||
|
||||
// Check-Common: {{READ of size 1 at 0x.* thread T0}}
|
||||
// Check-Common: {{ #0 0x.* in main .*heap-overflow.cc:6}}
|
||||
// Check-Common: {{0x.* is located 0 bytes to the right of 10-byte region}}
|
||||
// Check-Common: {{allocated by thread T0 here:}}
|
||||
|
||||
// Check-Linux: {{ #0 0x.* in .*malloc}}
|
||||
// Check-Linux: {{ #1 0x.* in main .*heap-overflow.cc:4}}
|
||||
|
||||
// Check-Darwin: {{ #0 0x.* in .*mz_malloc.*}}
|
||||
// Check-Darwin: {{ #1 0x.* in malloc_zone_malloc.*}}
|
||||
// Check-Darwin: {{ #2 0x.* in malloc.*}}
|
||||
// Check-Darwin: {{ #3 0x.* in main heap-overflow.cc:4}}
|
|
@ -1,17 +0,0 @@
|
|||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
extern "C" long strtol(const char *nptr, char **endptr, int base) {
|
||||
fprintf(stderr, "my_strtol_interceptor\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main() {
|
||||
char *x = (char*)malloc(10 * sizeof(char));
|
||||
free(x);
|
||||
return (int)strtol(x, 0, 10);
|
||||
}
|
||||
|
||||
// Check-Common: my_strtol_interceptor
|
||||
// CHECK-NOT: heap-use-after-free
|
||||
|
|
@ -1,19 +0,0 @@
|
|||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
|
||||
extern "C" void *__interceptor_malloc(size_t size);
|
||||
extern "C" void *malloc(size_t size) {
|
||||
write(2, "malloc call\n", sizeof("malloc call\n") - 1);
|
||||
return __interceptor_malloc(size);
|
||||
}
|
||||
|
||||
int main() {
|
||||
char *x = (char*)malloc(10 * sizeof(char));
|
||||
free(x);
|
||||
return (int)strtol(x, 0, 10);
|
||||
}
|
||||
|
||||
// Check-Common: malloc call
|
||||
// Check-Common: heap-use-after-free
|
||||
|
|
@ -1,18 +0,0 @@
|
|||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
extern "C" long __interceptor_strtol(const char *nptr, char **endptr, int base);
|
||||
extern "C" long strtol(const char *nptr, char **endptr, int base) {
|
||||
fprintf(stderr, "my_strtol_interceptor\n");
|
||||
return __interceptor_strtol(nptr, endptr, base);
|
||||
}
|
||||
|
||||
int main() {
|
||||
char *x = (char*)malloc(10 * sizeof(char));
|
||||
free(x);
|
||||
return (int)strtol(x, 0, 10);
|
||||
}
|
||||
|
||||
// Check-Common: my_strtol_interceptor
|
||||
// Check-Common: heap-use-after-free
|
||||
|
|
@ -1,48 +0,0 @@
|
|||
#include <stdlib.h>
|
||||
__attribute__((noinline))
|
||||
static void LargeFunction(int *x, int zero) {
|
||||
x[0]++;
|
||||
x[1]++;
|
||||
x[2]++;
|
||||
x[3]++;
|
||||
x[4]++;
|
||||
x[5]++;
|
||||
x[6]++;
|
||||
x[7]++;
|
||||
x[8]++;
|
||||
x[9]++;
|
||||
|
||||
x[zero + 111]++; // we should report this exact line
|
||||
|
||||
x[10]++;
|
||||
x[11]++;
|
||||
x[12]++;
|
||||
x[13]++;
|
||||
x[14]++;
|
||||
x[15]++;
|
||||
x[16]++;
|
||||
x[17]++;
|
||||
x[18]++;
|
||||
x[19]++;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
int *x = new int[100];
|
||||
LargeFunction(x, argc - 1);
|
||||
delete x;
|
||||
}
|
||||
|
||||
// Check-Common: {{.*ERROR: AddressSanitizer heap-buffer-overflow on address}}
|
||||
// Check-Common: {{0x.* at pc 0x.* bp 0x.* sp 0x.*}}
|
||||
// Check-Common: {{READ of size 4 at 0x.* thread T0}}
|
||||
|
||||
// atos incorrectly extracts the symbol name for the static functions on
|
||||
// Darwin.
|
||||
// Check-Linux: {{ #0 0x.* in LargeFunction.*large_func_test.cc:15}}
|
||||
// Check-Darwin: {{ #0 0x.* in .*LargeFunction.*large_func_test.cc:15}}
|
||||
|
||||
// Check-Common: {{ #1 0x.* in main .*large_func_test.cc:31}}
|
||||
// Check-Common: {{0x.* is located 44 bytes to the right of 400-byte region}}
|
||||
// Check-Common: {{allocated by thread T0 here:}}
|
||||
// Check-Common: {{ #0 0x.* in operator new.*}}
|
||||
// Check-Common: {{ #1 0x.* in main .*large_func_test.cc:30}}
|
|
@ -1,10 +0,0 @@
|
|||
#include <string.h>
|
||||
int main(int argc, char **argv) {
|
||||
char a1[] = {argc, 2, 3, 4};
|
||||
char a2[] = {1, 2*argc, 3, 4};
|
||||
// Check-Common: AddressSanitizer stack-buffer-overflow
|
||||
// Check-Common: {{#0.*memcmp}}
|
||||
// Check-Common: {{#1.*main}}
|
||||
int res = memcmp(a1, a2, 4 + argc); // BOOM
|
||||
return res;
|
||||
}
|
|
@ -1,17 +0,0 @@
|
|||
__attribute__((noinline))
|
||||
static void NullDeref(int *ptr) {
|
||||
ptr[10]++;
|
||||
}
|
||||
int main() {
|
||||
NullDeref((int*)0);
|
||||
}
|
||||
|
||||
// Check-Common: {{.*ERROR: AddressSanitizer crashed on unknown address}}
|
||||
// Check-Common: {{0x0*00028 .*pc 0x.*}}
|
||||
// Check-Common: {{AddressSanitizer can not provide additional info.}}
|
||||
|
||||
// atos on Mac cannot extract the symbol name correctly.
|
||||
// Check-Linux: {{ #0 0x.* in NullDeref.*null_deref.cc:3}}
|
||||
// Check-Darwin: {{ #0 0x.* in .*NullDeref.*null_deref.cc:3}}
|
||||
|
||||
// Check-Common: {{ #1 0x.* in main.*null_deref.cc:6}}
|
|
@ -1,21 +0,0 @@
|
|||
//===----------- shared-lib-test-so.cc --------------------------*- 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 AddressSanitizer, an address sanity checker.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
#include <stdio.h>
|
||||
|
||||
int pad[10];
|
||||
int GLOB[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
|
||||
|
||||
extern "C"
|
||||
void inc(int index) {
|
||||
GLOB[index]++;
|
||||
}
|
|
@ -1,42 +0,0 @@
|
|||
//===----------- shared-lib-test.cc -----------------------------*- 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 AddressSanitizer, an address sanity checker.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
#include <dlfcn.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <string>
|
||||
|
||||
using std::string;
|
||||
|
||||
typedef void (fun_t)(int x);
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
string path = string(argv[0]) + "-so.so";
|
||||
printf("opening %s ... \n", path.c_str());
|
||||
void *lib = dlopen(path.c_str(), RTLD_NOW);
|
||||
if (!lib) {
|
||||
printf("error in dlopen(): %s\n", dlerror());
|
||||
return 1;
|
||||
}
|
||||
fun_t *inc = (fun_t*)dlsym(lib, "inc");
|
||||
if (!inc) return 1;
|
||||
printf("ok\n");
|
||||
inc(1);
|
||||
inc(-1); // BOOM
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Check-Common: {{.*ERROR: AddressSanitizer global-buffer-overflow}}
|
||||
// Check-Common: {{READ of size 4 at 0x.* thread T0}}
|
||||
// Check-Common: {{ #0 0x.*}}
|
||||
// Check-Common: {{ #1 0x.* in main .*shared-lib-test.cc:35}}
|
|
@ -1,11 +0,0 @@
|
|||
#include <string.h>
|
||||
int main(int argc, char **argv) {
|
||||
char x[10];
|
||||
memset(x, 0, 10);
|
||||
int res = x[argc * 10]; // BOOOM
|
||||
return res;
|
||||
}
|
||||
|
||||
// Check-Common: {{READ of size 1 at 0x.* thread T0}}
|
||||
// Check-Common: {{ #0 0x.* in main .*stack-overflow.cc:5}}
|
||||
// Check-Common: {{Address 0x.* is .* frame <main>}}
|
|
@ -1,27 +0,0 @@
|
|||
#include <stdio.h>
|
||||
|
||||
__attribute__((noinline))
|
||||
char *Ident(char *x) {
|
||||
fprintf(stderr, "1: %p\n", x);
|
||||
return x;
|
||||
}
|
||||
|
||||
__attribute__((noinline))
|
||||
char *Func1() {
|
||||
char local;
|
||||
return Ident(&local);
|
||||
}
|
||||
|
||||
__attribute__((noinline))
|
||||
void Func2(char *x) {
|
||||
fprintf(stderr, "2: %p\n", x);
|
||||
*x = 1;
|
||||
// Check-Common: {{WRITE of size 1 .* thread T0}}
|
||||
// Check-Common: {{ #0.*Func2.*stack-use-after-return.cc:18}}
|
||||
// Check-Common: {{is located in frame <.*Func1.*> of T0's stack}}
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
Func2(Func1());
|
||||
return 0;
|
||||
}
|
|
@ -1,24 +0,0 @@
|
|||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
int main(int argc, char **argv) {
|
||||
char *hello = (char*)malloc(6);
|
||||
strcpy(hello, "hello");
|
||||
char *short_buffer = (char*)malloc(9);
|
||||
strncpy(short_buffer, hello, 10); // BOOM
|
||||
return short_buffer[8];
|
||||
}
|
||||
|
||||
// Check-Common: {{WRITE of size 1 at 0x.* thread T0}}
|
||||
// Check-Linux: {{ #0 0x.* in .*strncpy}}
|
||||
// Check-Darwin: {{ #0 0x.* in wrap_strncpy}}
|
||||
// Check-Common: {{ #1 0x.* in main .*strncpy-overflow.cc:7}}
|
||||
// Check-Common: {{0x.* is located 0 bytes to the right of 9-byte region}}
|
||||
// Check-Common: {{allocated by thread T0 here:}}
|
||||
|
||||
// Check-Linux: {{ #0 0x.* in .*malloc}}
|
||||
// Check-Linux: {{ #1 0x.* in main .*strncpy-overflow.cc:6}}
|
||||
|
||||
// Check-Darwin: {{ #0 0x.* in .*mz_malloc.*}}
|
||||
// Check-Darwin: {{ #1 0x.* in malloc_zone_malloc.*}}
|
||||
// Check-Darwin: {{ #2 0x.* in malloc.*}}
|
||||
// Check-Darwin: {{ #3 0x.* in main .*strncpy-overflow.cc:6}}
|
|
@ -1,99 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
set -e # fail on any error
|
||||
|
||||
OS=`uname`
|
||||
CXX=$1
|
||||
CC=$2
|
||||
FILE_CHECK=$3
|
||||
CXXFLAGS="-mno-omit-leaf-frame-pointer -fno-omit-frame-pointer -fno-optimize-sibling-calls -g"
|
||||
SYMBOLIZER=../scripts/asan_symbolize.py
|
||||
ASAN_INTERFACE_H=../../../include/sanitizer/asan_interface.h
|
||||
TMP_ASAN_REPORT=asan_report.tmp
|
||||
|
||||
run_program() {
|
||||
./$1 2>&1 | $SYMBOLIZER 2> /dev/null | c++filt > $TMP_ASAN_REPORT
|
||||
}
|
||||
|
||||
# check_program exe_file source_file check_prefixf
|
||||
check_program() {
|
||||
run_program $1
|
||||
$FILE_CHECK $2 --check-prefix=$3 < $TMP_ASAN_REPORT
|
||||
rm -f $TMP_ASAN_REPORT
|
||||
}
|
||||
|
||||
C_TEST=use-after-free
|
||||
echo "Sanity checking a test in pure C"
|
||||
$CC -g -faddress-sanitizer -O2 $C_TEST.c
|
||||
check_program a.out $C_TEST.c CHECK
|
||||
rm ./a.out
|
||||
|
||||
echo "Sanity checking a test in pure C with -pie"
|
||||
$CC -g -faddress-sanitizer -O2 $C_TEST.c -pie
|
||||
check_program a.out $C_TEST.c CHECK
|
||||
rm ./a.out
|
||||
|
||||
echo "Testing sleep_before_dying"
|
||||
$CC -g -faddress-sanitizer -O2 $C_TEST.c
|
||||
export ASAN_OPTIONS="sleep_before_dying=1"
|
||||
check_program a.out $C_TEST.c CHECKSLEEP
|
||||
export ASAN_OPTIONS=""
|
||||
rm ./a.out
|
||||
|
||||
echo "Checking strip_path_prefix option"
|
||||
$CC -g -faddress-sanitizer -O2 $C_TEST.c
|
||||
export ASAN_OPTIONS="strip_path_prefix='/'"
|
||||
./a.out 2>&1 | $FILE_CHECK $C_TEST.c --check-prefix=CHECKSTRIP
|
||||
export ASAN_OPTIONS=""
|
||||
rm ./a.out
|
||||
|
||||
echo "Checking the presense of interface symbols in compiled file"
|
||||
$CC -g -faddress-sanitizer -dead_strip -O2 $C_TEST.c
|
||||
nm ./a.out | egrep " [TW] " | sed "s/.* T //" | sed "s/.* W //" | grep "__asan_" | sed "s/___asan_/__asan_/" > symbols.txt
|
||||
cat $ASAN_INTERFACE_H | sed "s/\/\/.*//" | sed "s/typedef.*//" | grep "__asan_.*(" | sed "s/.* __asan_/__asan_/;s/(.*//" > interface.txt
|
||||
for i in __asan_report_{load,store}{1,2,4,8,16}
|
||||
do
|
||||
echo $i >> interface.txt
|
||||
done
|
||||
cat interface.txt | sort | uniq | diff symbols.txt - || exit 1
|
||||
rm ./a.out interface.txt symbols.txt
|
||||
|
||||
|
||||
# FIXME: some tests do not need to be ran for all the combinations of arch
|
||||
# and optimization mode.
|
||||
for t in *.cc; do
|
||||
for b in 32 64; do
|
||||
for O in 0 1 2 3; do
|
||||
c=`basename $t .cc`
|
||||
if [[ "$c" == *"-so" ]]; then
|
||||
continue
|
||||
fi
|
||||
if [[ "$c" == *"-linux" ]]; then
|
||||
if [[ "$OS" != "Linux" ]]; then
|
||||
continue
|
||||
fi
|
||||
fi
|
||||
c_so=$c-so
|
||||
exe=$c.$b.O$O
|
||||
so=$c.$b.O$O-so.so
|
||||
echo testing $exe
|
||||
build_command="$CXX $CXXFLAGS -m$b -faddress-sanitizer -O$O $c.cc -o $exe"
|
||||
[ "$DEBUG" == "1" ] && echo $build_command
|
||||
$build_command
|
||||
[ -e "$c_so.cc" ] && $CXX $CXXFLAGS -m$b -faddress-sanitizer -O$O $c_so.cc -fPIC -shared -o $so
|
||||
run_program $exe
|
||||
# Check common expected lines for OS.
|
||||
$FILE_CHECK $c.cc --check-prefix="Check-Common" < $TMP_ASAN_REPORT
|
||||
# Check OS-specific lines.
|
||||
if [ `grep -c "Check-$OS" $c.cc` -gt 0 ]
|
||||
then
|
||||
$FILE_CHECK $c.cc --check-prefix="Check-$OS" < $TMP_ASAN_REPORT
|
||||
fi
|
||||
rm ./$exe
|
||||
rm ./$TMP_ASAN_REPORT
|
||||
[ -e "$so" ] && rm ./$so
|
||||
done
|
||||
done
|
||||
done
|
||||
|
||||
exit 0
|
|
@ -1,14 +0,0 @@
|
|||
#include <stdlib.h>
|
||||
int main() {
|
||||
char *x = (char*)malloc(10 * sizeof(char));
|
||||
free(x);
|
||||
return x[5];
|
||||
}
|
||||
|
||||
// CHECK: heap-use-after-free
|
||||
// CHECK: free
|
||||
// CHECK: main{{.*}}use-after-free.c:4
|
||||
// CHECK: malloc
|
||||
// CHECK: main{{.*}}use-after-free.c:3
|
||||
// CHECKSLEEP: Sleeping for 1 second
|
||||
// CHECKSTRIP-NOT: #0 0x{{.*}} ({{[/].*}})
|
|
@ -1,31 +0,0 @@
|
|||
#include <stdlib.h>
|
||||
int main() {
|
||||
char *x = (char*)malloc(10 * sizeof(char));
|
||||
free(x);
|
||||
return x[5];
|
||||
}
|
||||
|
||||
// Check-Common: {{.*ERROR: AddressSanitizer heap-use-after-free on address}}
|
||||
// Check-Common: {{0x.* at pc 0x.* bp 0x.* sp 0x.*}}
|
||||
// Check-Common: {{READ of size 1 at 0x.* thread T0}}
|
||||
// Check-Common: {{ #0 0x.* in main .*use-after-free.cc:5}}
|
||||
// Check-Common: {{0x.* is located 5 bytes inside of 10-byte region .0x.*,0x.*}}
|
||||
// Check-Common: {{freed by thread T0 here:}}
|
||||
|
||||
// Check-Linux: {{ #0 0x.* in .*free}}
|
||||
// Check-Linux: {{ #1 0x.* in main .*use-after-free.cc:4}}
|
||||
|
||||
// Check-Darwin: {{ #0 0x.* in .*mz_free.*}}
|
||||
// We override free() on Darwin, thus no malloc_zone_free
|
||||
// Check-Darwin: {{ #1 0x.* in wrap_free}}
|
||||
// Check-Darwin: {{ #2 0x.* in main .*use-after-free.cc:4}}
|
||||
|
||||
// Check-Common: {{previously allocated by thread T0 here:}}
|
||||
|
||||
// Check-Linux: {{ #0 0x.* in .*malloc}}
|
||||
// Check-Linux: {{ #1 0x.* in main .*use-after-free.cc:3}}
|
||||
|
||||
// Check-Darwin: {{ #0 0x.* in .*mz_malloc.*}}
|
||||
// Check-Darwin: {{ #1 0x.* in malloc_zone_malloc.*}}
|
||||
// Check-Darwin: {{ #2 0x.* in malloc.*}}
|
||||
// Check-Darwin: {{ #3 0x.* in main .*use-after-free.cc:3}}
|
Loading…
Reference in New Issue