[ASan] Nuke output_tests/ in favor of lit_tests/. Stop using Makefile.old.

llvm-svn: 163294
This commit is contained in:
Alexey Samsonov 2012-09-06 06:39:02 +00:00
parent f3e4aa8cdd
commit ac87a5bddc
23 changed files with 15 additions and 615 deletions

View File

@ -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

View File

@ -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

View File

@ -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];
}

View File

@ -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;
}

View File

@ -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__);
}

View 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;
}

View File

@ -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;
}

View File

@ -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}}

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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}}

View File

@ -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;
}

View File

@ -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}}

View File

@ -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]++;
}

View File

@ -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}}

View File

@ -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>}}

View File

@ -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;
}

View File

@ -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}}

View File

@ -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

View File

@ -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{{.*}} ({{[/].*}})

View File

@ -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}}