Imported Upstream version 6.10.0.49

Former-commit-id: 1d6753294b2993e1fbf92de9366bb9544db4189b
This commit is contained in:
Xamarin Public Jenkins (auto-signing)
2020-01-16 16:38:04 +00:00
parent d94e79959b
commit 468663ddbb
48518 changed files with 2789335 additions and 61176 deletions

View File

@@ -0,0 +1,29 @@
// RUN: %clang_cl_asan -O0 %s -Fe%t
// RUN: %run %t
#include <windows.h>
#define CHECK_ALIGNED(ptr,alignment) \
do { \
if (((uintptr_t)(ptr) % (alignment)) != 0) \
return __LINE__; \
} \
while(0)
int main(void) {
int *p = (int*)_aligned_malloc(1024 * sizeof(int), 32);
CHECK_ALIGNED(p, 32);
p[512] = 0;
_aligned_free(p);
p = (int*)_aligned_malloc(128, 128);
CHECK_ALIGNED(p, 128);
p = (int*)_aligned_realloc(p, 2048 * sizeof(int), 128);
CHECK_ALIGNED(p, 128);
p[1024] = 0;
if (_aligned_msize(p, 128, 0) != 2048 * sizeof(int))
return __LINE__;
_aligned_free(p);
return 0;
}

View File

@@ -0,0 +1,37 @@
// RUN: %clang_cl_asan -O0 %s -Fe%t
// RUN: %run %t | FileCheck %s
#include <malloc.h>
#include <stdio.h>
int main() {
int *p = (int*)malloc(1024 * sizeof(int));
p[512] = 0;
free(p);
p = (int*)malloc(128);
p = (int*)realloc(p, 2048 * sizeof(int));
p[1024] = 0;
free(p);
p = (int*)calloc(16, sizeof(int));
if (p[8] != 0)
return 1;
p[15]++;
if (16 * sizeof(int) != _msize(p))
return 2;
free(p);
p = new int;
*p = 42;
delete p;
p = new int[42];
p[15]++;
delete [] p;
printf("All ok\n");
// CHECK: All ok
return 0;
}

View File

@@ -0,0 +1,21 @@
// RUN: %clang_cl_asan -O0 %s -Fe%t
// RUN: %run %t
#include <windows.h>
#include <process.h>
unsigned WINAPI thread_proc(void *) {
volatile char stack_buffer[42];
for (int i = 0; i < sizeof(stack_buffer); ++i)
stack_buffer[i] = 42;
return 0;
}
int main() {
HANDLE thr = (HANDLE)_beginthreadex(NULL, 0, thread_proc, NULL, 0, NULL);
if (thr == 0)
return 1;
if (WAIT_OBJECT_0 != WaitForSingleObject(thr, INFINITE))
return 2;
CloseHandle(thr);
}

View File

@@ -0,0 +1,61 @@
// Make sure we can throw exceptions from work items executed via
// BindIoCompletionCallback.
//
// RUN: %clangxx_asan %s -o %t.exe
// RUN: %run %t.exe 2>&1 | FileCheck %s
#include <windows.h>
#include <stdio.h>
void ThrowAndCatch();
__declspec(noinline)
void Throw() {
fprintf(stderr, "Throw\n");
// CHECK: Throw
throw 1;
}
void ThrowAndCatch() {
int local;
try {
Throw();
} catch(...) {
fprintf(stderr, "Catch\n");
// CHECK: Catch
}
}
char buffer[65536];
HANDLE done;
OVERLAPPED ov;
void CALLBACK completion_callback(DWORD error, DWORD bytesRead,
LPOVERLAPPED pov) {
ThrowAndCatch();
SetEvent(done);
}
int main(int argc, char **argv) {
done = CreateEvent(0, false, false, "job is done");
if (!done)
return 1;
HANDLE file = CreateFile(
argv[0], GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_NO_BUFFERING | FILE_FLAG_OVERLAPPED,
NULL);
if (!file)
return 2;
if (!BindIoCompletionCallback(file, completion_callback, 0))
return 3;
if (!ReadFile(file, buffer, sizeof(buffer), NULL, &ov) &&
GetLastError() != ERROR_IO_PENDING)
return 4;
if (WAIT_OBJECT_0 != WaitForSingleObject(done, 10 * 1000))
return 5;
fprintf(stderr, "Done!\n");
// CHECK: Done!
}

View File

@@ -0,0 +1,21 @@
// RUN: %clang_cl_asan -O0 %s -Fe%t
// RUN: %run %t
#include <windows.h>
typedef struct _S {
unsigned int bf1:1;
unsigned int bf2:2;
unsigned int bf3:3;
unsigned int bf4:4;
} S;
int main(void) {
S *s = (S*)malloc(sizeof(S));
s->bf1 = 1;
s->bf2 = 2;
s->bf3 = 3;
s->bf4 = 4;
free(s);
return 0;
}

View File

@@ -0,0 +1,34 @@
// RUN: %clang_cl_asan -O0 %s -Fe%t
// RUN: not %run %t 2>&1 | FileCheck %s
#include <windows.h>
typedef struct _S {
unsigned int bf1:1;
unsigned int bf2:2;
unsigned int bf3:3;
unsigned int bf4:4;
} S;
void make_access(S *s) {
s->bf2 = 2;
// CHECK: AddressSanitizer: heap-use-after-free on address [[ADDR:0x[0-9a-f]+]]
// CHECK: READ of size {{[124]}} at [[ADDR]]
// CHECK: {{#0 .* make_access.*bitfield_uaf.cc}}:[[@LINE-3]]
// CHECK: {{#1 .* main}}
}
int main(void) {
S *s = (S*)malloc(sizeof(S));
free(s);
// CHECK: [[ADDR]] is located 0 bytes inside of 4-byte region
// CHECK-LABEL: freed by thread T0 here:
// CHECK: {{#0 .* free }}
// CHECK: {{#1 .* main .*bitfield_uaf.cc}}:[[@LINE-4]]
// CHECK-LABEL: previously allocated by thread T0 here:
// CHECK: {{#0 .* malloc }}
// CHECK: {{#1 .* main .*bitfield_uaf.cc}}:[[@LINE-8]]
make_access(s);
return 0;
}

View File

@@ -0,0 +1,17 @@
// RUN: %clang_cl_asan -O0 %s -Fe%t
// RUN: not %run %t 2>&1 | FileCheck %s
#include <malloc.h>
int main() {
int *buffer = (int*)calloc(42, sizeof(int));
buffer[-1] = 42;
// CHECK: AddressSanitizer: heap-buffer-overflow on address [[ADDR:0x[0-9a-f]+]]
// CHECK: WRITE of size 4 at [[ADDR]] thread T0
// CHECK-NEXT: {{#0 .* main .*calloc_left_oob.cc}}:[[@LINE-3]]
// CHECK: [[ADDR]] is located 4 bytes to the left of 168-byte region
// CHECK: allocated by thread T0 here:
// CHECK-NEXT: {{#0 .* calloc }}
// CHECK-NEXT: {{#1 .* main .*calloc_left_oob.cc}}:[[@LINE-8]]
free(buffer);
}

View File

@@ -0,0 +1,17 @@
// RUN: %clang_cl_asan -O0 %s -Fe%t
// RUN: not %run %t 2>&1 | FileCheck %s
#include <malloc.h>
int main() {
int *buffer = (int*)calloc(42, sizeof(int));
buffer[42] = 42;
// CHECK: AddressSanitizer: heap-buffer-overflow on address [[ADDR:0x[0-9a-f]+]]
// CHECK: WRITE of size 4 at [[ADDR]] thread T0
// CHECK-NEXT: {{#0 .* main .*calloc_right_oob.cc}}:[[@LINE-3]]
// CHECK: [[ADDR]] is located 0 bytes to the right of 168-byte region
// CHECK: allocated by thread T0 here:
// CHECK-NEXT: {{#0 .* calloc }}
// CHECK-NEXT: {{#1 .* main .*calloc_right_oob.cc}}:[[@LINE-8]]
free(buffer);
}

View File

@@ -0,0 +1,20 @@
// RUN: %clang_cl_asan -O0 %s -Fe%t
// RUN: not %run %t 2>&1 | FileCheck %s
#include <malloc.h>
int main() {
int *buffer = (int*)calloc(42, sizeof(int));
free(buffer);
buffer[0] = 42;
// CHECK: AddressSanitizer: heap-use-after-free on address [[ADDR:0x[0-9a-f]+]]
// CHECK: WRITE of size 4 at [[ADDR]] thread T0
// CHECK-NEXT: {{#0 .* main .*calloc_uaf.cc}}:[[@LINE-3]]
// CHECK: [[ADDR]] is located 0 bytes inside of 168-byte region
// CHECK: freed by thread T0 here:
// CHECK-NEXT: {{#0 .* free }}
// CHECK-NEXT: {{#1 .* main .*calloc_uaf.cc}}:[[@LINE-8]]
// CHECK: previously allocated by thread T0 here:
// CHECK-NEXT: {{#0 .* calloc }}
// CHECK-NEXT: {{#1 .* main .*calloc_uaf.cc}}:[[@LINE-12]]
}

View File

@@ -0,0 +1,25 @@
// RUN: rm -rf %T/coverage-basic
// RUN: mkdir %T/coverage-basic && cd %T/coverage-basic
// RUN: %clangxx_asan -fsanitize-coverage=func %s -o test.exe
// RUN: %env_asan_opts=coverage=1 %run ./test.exe
//
// RUN: %sancov print *.sancov | FileCheck %s
#include <stdio.h>
void foo() { fputs("FOO", stderr); }
void bar() { fputs("BAR", stderr); }
int main(int argc, char **argv) {
if (argc == 2) {
foo();
bar();
} else {
bar();
foo();
}
}
// CHECK: 0x{{[0-9a-f]*}}
// CHECK: 0x{{[0-9a-f]*}}
// CHECK: 0x{{[0-9a-f]*}}
// CHECK-NOT: 0x{{[0-9a-f]*}}

View File

@@ -0,0 +1,16 @@
// Test that coverage and MSVC CRT stdio work from a DLL. This ensures that the
// __local_stdio_printf_options function isn't instrumented for coverage.
// RUN: rm -rf %t && mkdir %t && cd %t
// RUN: %clang_cl_asan -fsanitize-coverage=func,trace-pc-guard -O0 %p/dll_host.cc -Fet.exe
// RUN: %clang_cl_asan -fsanitize-coverage=func,trace-pc-guard -LD -O0 %s -Fet.dll
// RUN: %run ./t.exe t.dll 2>&1 | FileCheck %s
#include <stdio.h>
extern "C" __declspec(dllexport)
int test_function() {
printf("hello world\n");
// CHECK: hello world
return 0;
}

View File

@@ -0,0 +1,29 @@
// RUN: %clangxx_asan -std=c++11 -O0 %s -o %t
// RUN: not %run %t 2>&1 | FileCheck %s --check-prefix=READ
// RUN: not %run %t write 2>&1 | FileCheck %s --check-prefix=WRITE
#include <windows.h>
#include <stdio.h>
static volatile int sink;
__attribute__((noinline)) void Read(int *ptr) { sink = *ptr; }
__attribute__((noinline)) void Write(int *ptr) { *ptr = 0; }
int main(int argc, char **argv) {
// Writes to shadow are detected as reads from shadow gap (because of how the
// shadow mapping works). This is kinda hard to fix. Test a random address in
// the application part of the address space.
void *volatile p = VirtualAlloc(0, 4096, MEM_COMMIT, PAGE_READONLY);
bool ok = VirtualFree(p, 0, MEM_RELEASE);
if (!ok) {
printf("VirtualFree failed\n");
return 0;
}
if (argc == 1)
Read((int *)p);
else
Write((int *)p);
}
// READ: AddressSanitizer: access-violation on unknown address
// READ: The signal is caused by a READ memory access.
// WRITE: AddressSanitizer: access-violation on unknown address
// WRITE: The signal is caused by a WRITE memory access.

View File

@@ -0,0 +1,31 @@
// RUN: %clang_cl_asan -O0 %s -Fe%t
// RUN: %run %t | FileCheck %s
// This is a test for http://code.google.com/p/address-sanitizer/issues/detail?id=305
#include <stdio.h>
typedef void (*FPTR)();
// __xi_a and __xi_z are defined in VC/crt/src/crt0dat.c
// and are located in .CRT$XIA and .CRT$XIZ respectively.
extern "C" FPTR __xi_a, __xi_z;
int main() {
unsigned count = 0;
// Iterate through CRT initializers.
for (FPTR* it = &__xi_a; it < &__xi_z; ++it) {
if (*it)
count++;
}
printf("Number of nonzero CRT initializers: %u\n", count);
// CHECK: Number of nonzero CRT initializers
}
void call_me_maybe() {}
#pragma data_seg(".CRT$XIB")
// Add an initializer that shouldn't get its own redzone.
FPTR run_on_startup = call_me_maybe;

View File

@@ -0,0 +1,18 @@
// Build an executable with ASan, then extract the DLLs that it depends on.
// RUN: %clang_cl_asan %s -Fe%t.exe
// RUN: llvm-readobj -coff-imports %t.exe | grep Name: | sed -e 's/ *Name: *//' > %t
//
// Make sure the binary doesn't depend on dbghelp directly.
// RUN: not grep dbghelp.dll %t
//
// Make sure any clang_rt DLLs it depends on don't depend on dbghelp. In the
// static build, there won't be any clang_rt DLLs.
// RUN: not grep cl""ang_rt %t || \
// RUN: grep cl""ang_rt %t | xargs which | \
// RUN: xargs llvm-readobj -coff-imports | not grep dbghelp.dll %t
extern "C" int puts(const char *);
int main() {
puts("main");
}

View File

@@ -0,0 +1,50 @@
// RUN: %clang_cl_asan -O0 %s -Fe%t
// RUN: not %run %t 2>&1 | FileCheck %s
//
// This test makes sure ASan symbolizes stack traces the way they are typically
// symbolized on Windows.
#include <malloc.h>
namespace foo {
// A template function in a namespace.
template<int x>
void bar(char *p) {
*p = x;
}
// A regular function in a namespace.
void spam(char *p) {
bar<42>(p);
}
}
// A multi-argument template with a bool template parameter.
template<typename T, bool U>
void baz(T t) {
if (U)
foo::spam(t);
}
template<typename T>
struct A {
A(T v) { v_ = v; }
~A();
char *v_;
};
// A destructor of a template class.
template<>
A<char*>::~A() {
baz<char*, true>(v_);
}
int main() {
char *buffer = (char*)malloc(42);
free(buffer);
A<char*> a(buffer);
// CHECK: AddressSanitizer: heap-use-after-free on address [[ADDR:0x[0-9a-f]+]]
// CHECK: foo::bar<42>{{.*}}demangled_names.cc
// CHECK: foo::spam{{.*}}demangled_names.cc
// CHECK: baz<char *,1>{{.*}}demangled_names.cc
// CHECK: A<char *>::~A<char *>{{.*}}demangled_names.cc
}

View File

@@ -0,0 +1,34 @@
// RUN: %clang_cl_asan -O0 %p/dll_host.cc -Fe%t
// RUN: %clang_cl_asan -LD -O0 %s -Fe%t.dll
// RUN: %run %t %t.dll | FileCheck %s
#include <malloc.h>
#include <stdio.h>
#define CHECK_ALIGNED(ptr,alignment) \
do { \
if (((uintptr_t)(ptr) % (alignment)) != 0) \
return __LINE__; \
} \
while(0)
extern "C" __declspec(dllexport)
int test_function() {
int *p = (int*)_aligned_malloc(1024 * sizeof(int), 32);
CHECK_ALIGNED(p, 32);
p[512] = 0;
_aligned_free(p);
p = (int*)_aligned_malloc(128, 128);
CHECK_ALIGNED(p, 128);
p = (int*)_aligned_realloc(p, 2048 * sizeof(int), 128);
CHECK_ALIGNED(p, 128);
p[1024] = 0;
if (_aligned_msize(p, 128, 0) != 2048 * sizeof(int))
return __LINE__;
_aligned_free(p);
printf("All ok\n");
// CHECK: All ok
return 0;
}

View File

@@ -0,0 +1,39 @@
// RUN: %clang_cl_asan -O0 %p/dll_host.cc -Fe%t
// RUN: %clang_cl_asan -LD -O0 %s -Fe%t.dll
// RUN: %run %t %t.dll | FileCheck %s
#include <malloc.h>
#include <stdio.h>
extern "C" __declspec(dllexport)
int test_function() {
int *p = (int*)malloc(1024 * sizeof(int));
p[512] = 0;
free(p);
p = (int*)malloc(128);
p = (int*)realloc(p, 2048 * sizeof(int));
p[1024] = 0;
free(p);
p = (int*)calloc(16, sizeof(int));
if (p[8] != 0)
return 1;
p[15]++;
if (16 * sizeof(int) != _msize(p))
return 2;
free(p);
p = new int;
*p = 42;
delete p;
p = new int[42];
p[15]++;
delete [] p;
printf("All ok\n");
// CHECK: All ok
return 0;
}

View File

@@ -0,0 +1,19 @@
// Just make sure we can link an implib into another DLL
// This used to fail between r212699 and r212814.
// RUN: %clang_cl_asan -DCONFIG=1 %s -c -Fo%t.1.obj
// RUN: link /nologo /DLL /OUT:%t.1.dll %t.1.obj %asan_dll_thunk
// RUN: %clang_cl_asan -DCONFIG=2 %s -c -Fo%t.2.obj
// RUN: link /nologo /DLL /OUT:%t.2.dll %t.2.obj %t.1.lib %asan_dll_thunk
// REQUIRES: asan-static-runtime
#if CONFIG==1
extern "C" __declspec(dllexport) int f1() {
int x = 0;
return 1;
}
#else
extern "C" __declspec(dllexport) int f2() {
int x = 0;
return 2;
}
#endif

View File

@@ -0,0 +1,23 @@
// RUN: %clang_cl_asan -O0 %p/dll_host.cc -Fe%t
// RUN: %clang_cl_asan -LD -O0 %s -Fe%t.dll
// RUN: %run %t %t.dll 2>&1 | FileCheck %s
// Test that it works correctly even with ICF enabled.
// RUN: %clang_cl_asan -LD -O0 %s -Fe%t.dll -link /OPT:REF /OPT:ICF
// RUN: %run %t %t.dll 2>&1 | FileCheck %s
#include <iostream>
extern "C" __declspec(dllexport)
int test_function() {
// Just make sure we can use cout.
std::cout << "All ok\n";
// CHECK: All ok
// This line forces a declaration of some global basic_ostream internal object that
// calls memcpy() in its constructor. This doesn't work if __asan_init is not
// called early enough.
std::cout << 42;
// CHECK: 42
return 0;
}

View File

@@ -0,0 +1,130 @@
// RUN: %clang_cl_asan -O0 %p/dll_host.cc -Fe%t
// RUN: %clang_cl_asan -LD -O2 %s -Fe%t.dll
// RUNX: %run %t %t.dll 2>&1 | FileCheck %s
// Check that ASan does not CHECK fail when SEH is used around a crash from a
// thread injected by control C.
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
static void __declspec(noinline) CrashOnProcessDetach() {
printf("CrashOnProcessDetach\n");
fflush(stdout);
*static_cast<volatile int *>(0) = 0x356;
}
bool g_is_child = false;
BOOL WINAPI DllMain(PVOID h, DWORD reason, PVOID reserved) {
if (reason == DLL_PROCESS_DETACH && g_is_child) {
printf("in DllMain DLL_PROCESS_DETACH\n");
fflush(stdout);
__try {
CrashOnProcessDetach();
} __except (1) {
printf("caught crash\n");
fflush(stdout);
}
}
return true;
}
static void run_child() {
// Send this process group Ctrl+C. That should only be this process.
printf("GenerateConsoleCtrlEvent\n");
fflush(stdout);
GenerateConsoleCtrlEvent(CTRL_C_EVENT, 0);
Sleep(10 * 1000); // Wait 10 seconds, and the process should die.
printf("unexpected execution after interrupt\n");
fflush(stdout);
exit(0x42);
}
static int WINAPI ignore_control_c(DWORD ctrl_type) {
// Don't interrupt the parent.
return ctrl_type == CTRL_C_EVENT;
}
static int run_parent() {
// Set an environment variable to tell the child process to interrupt itself.
if (!SetEnvironmentVariableW(L"DO_CONTROL_C", L"1")) {
printf("SetEnvironmentVariableW failed (0x%8lx).\n", GetLastError());
fflush(stdout);
return 2;
}
// Launch a new process using the current executable with a new console.
// Ctrl-C events are console-wide, so we need a new console.
STARTUPINFOW si;
memset(&si, 0, sizeof(si));
si.cb = sizeof(si);
// Hides the new console window that we are creating.
si.dwFlags |= STARTF_USESHOWWINDOW;
si.wShowWindow = SW_HIDE;
// Ensures that stdout still goes to the parent despite the new console.
si.dwFlags |= STARTF_USESTDHANDLES;
si.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
si.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
si.hStdError = GetStdHandle(STD_ERROR_HANDLE);
PROCESS_INFORMATION pi;
memset(&pi, 0, sizeof(pi));
int flags = CREATE_NO_WINDOW | CREATE_NEW_PROCESS_GROUP | CREATE_NEW_CONSOLE;
if (!CreateProcessW(nullptr, // No module name (use command line)
GetCommandLineW(), // Command line
nullptr, // Process handle not inheritable
nullptr, // Thread handle not inheritable
TRUE, // Set handle inheritance to TRUE
flags, // Flags to give the child a console
nullptr, // Use parent's environment block
nullptr, // Use parent's starting directory
&si, &pi)) {
printf("CreateProcess failed (0x%08lx).\n", GetLastError());
fflush(stdout);
return 2;
}
// Wait until child process exits.
if (WaitForSingleObject(pi.hProcess, INFINITE) == WAIT_FAILED) {
printf("WaitForSingleObject failed (0x%08lx).\n", GetLastError());
fflush(stdout);
return 2;
}
// Get the exit code. It should be the one for ctrl-c events.
DWORD rc;
if (!GetExitCodeProcess(pi.hProcess, &rc)) {
printf("GetExitCodeProcess failed (0x%08lx).\n", GetLastError());
fflush(stdout);
return 2;
}
if (rc == STATUS_CONTROL_C_EXIT)
printf("child quit with STATUS_CONTROL_C_EXIT\n");
else
printf("unexpected exit code: 0x%08lx\n", rc);
fflush(stdout);
// Close process and thread handles.
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
return 0;
}
// CHECK: in DllMain DLL_PROCESS_DETACH
// CHECK: CrashOnProcessDetach
// CHECK: caught crash
// CHECK: child quit with STATUS_CONTROL_C_EXIT
extern "C" int __declspec(dllexport) test_function() {
wchar_t buf[260];
int len = GetEnvironmentVariableW(L"DO_CONTROL_C", buf, 260);
if (len > 0) {
g_is_child = true;
run_child();
} else {
exit(run_parent());
}
return 0;
}

Some files were not shown because too many files have changed in this diff Show More