Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[ASan] New approach to dynamic allocas unpoisoning. Patch by Max Osta…
…penko! Differential Revision: http://reviews.llvm.org/D7098 llvm-svn: 238401
- Loading branch information
Yury Gribov
committed
May 28, 2015
1 parent
f841d3a
commit 63d9764
Showing
8 changed files
with
172 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
32 changes: 32 additions & 0 deletions
32
compiler-rt/test/asan/TestCases/alloca_loop_unpoisoning.cc
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
// RUN: %clangxx_asan -O0 -mllvm -asan-instrument-allocas %s -o %t | ||
// RUN: %run %t 2>&1 | ||
// | ||
|
||
// This testcase checks that allocas and VLAs inside loop are correctly unpoisoned. | ||
|
||
#include <assert.h> | ||
#include <alloca.h> | ||
#include <stdint.h> | ||
#include "sanitizer/asan_interface.h" | ||
|
||
void *top, *bot; | ||
|
||
__attribute__((noinline)) void foo(int len) { | ||
char x; | ||
top = &x; | ||
char array[len]; // NOLINT | ||
assert(!(reinterpret_cast<uintptr_t>(array) & 31L)); | ||
alloca(len); | ||
for (int i = 0; i < 32; ++i) { | ||
char array[i]; // NOLINT | ||
bot = alloca(i); | ||
assert(!(reinterpret_cast<uintptr_t>(bot) & 31L)); | ||
} | ||
} | ||
|
||
int main(int argc, char **argv) { | ||
foo(32); | ||
void *q = __asan_region_is_poisoned(bot, (char *)top - (char *)bot); | ||
assert(!q); | ||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
// RUN: %clangxx_asan -O0 -mllvm -asan-instrument-allocas %s -o %t | ||
// RUN: %run %t 2>&1 | ||
// | ||
|
||
// This testcase checks correct interaction between VLAs and allocas. | ||
|
||
#include <assert.h> | ||
#include <alloca.h> | ||
#include <stdint.h> | ||
#include "sanitizer/asan_interface.h" | ||
|
||
#define RZ 32 | ||
|
||
__attribute__((noinline)) void foo(int len) { | ||
char *top, *bot; | ||
// This alloca call should live until the end of foo. | ||
char *alloca1 = (char *)alloca(len); | ||
assert(!(reinterpret_cast<uintptr_t>(alloca1) & 31L)); | ||
// This should be first poisoned address after loop. | ||
top = alloca1 - RZ; | ||
for (int i = 0; i < 32; ++i) { | ||
// Check that previous alloca was unpoisoned at the end of iteration. | ||
if (i) assert(!__asan_region_is_poisoned(bot, 96)); | ||
// VLA is unpoisoned at the end of iteration. | ||
volatile char array[i]; | ||
assert(!(reinterpret_cast<uintptr_t>(array) & 31L)); | ||
// Alloca is unpoisoned at the end of iteration, | ||
// because dominated by VLA. | ||
bot = (char *)alloca(i) - RZ; | ||
} | ||
// Check that all allocas from loop were unpoisoned correctly. | ||
void *q = __asan_region_is_poisoned(bot, (char *)top - (char *)bot + 1); | ||
assert(q == top); | ||
} | ||
|
||
int main(int argc, char **argv) { | ||
foo(32); | ||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
// RUN: %clangxx_asan -O0 -mllvm -asan-instrument-allocas %s -o %t | ||
// RUN: not %run %t 2>&1 | FileCheck %s | ||
// | ||
|
||
// This is reduced testcase based on Chromium code. | ||
// See http://reviews.llvm.org/D6055?vs=on&id=15616&whitespace=ignore-all#toc. | ||
|
||
#include <stdint.h> | ||
#include <assert.h> | ||
|
||
int a = 7; | ||
int b; | ||
int c; | ||
int *p; | ||
|
||
__attribute__((noinline)) void fn3(int *first, int second) { | ||
} | ||
|
||
int main() { | ||
int d = b && c; | ||
int e[a]; // NOLINT | ||
assert(!(reinterpret_cast<uintptr_t>(e) & 31L)); | ||
int f; | ||
if (d) | ||
fn3(&f, sizeof 0 * (&c - e)); | ||
e[a] = 0; | ||
// CHECK: ERROR: AddressSanitizer: dynamic-stack-buffer-overflow on address [[ADDR:0x[0-9a-f]+]] | ||
// CHECK: WRITE of size 4 at [[ADDR]] thread T0 | ||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
// RUN: %clangxx_asan -O0 -mllvm -asan-instrument-allocas %s -o %t | ||
// RUN: not %run %t 2>&1 | FileCheck %s | ||
// | ||
|
||
#include <assert.h> | ||
#include <stdint.h> | ||
|
||
__attribute__((noinline)) void foo(int index, int len) { | ||
if (index > len) { | ||
char str[len]; //NOLINT | ||
assert(!(reinterpret_cast<uintptr_t>(str) & 31L)); | ||
str[index] = '1'; // BOOM | ||
// CHECK: ERROR: AddressSanitizer: dynamic-stack-buffer-overflow on address [[ADDR:0x[0-9a-f]+]] | ||
// CHECK: WRITE of size 1 at [[ADDR]] thread T0 | ||
} | ||
} | ||
|
||
int main(int argc, char **argv) { | ||
foo(33, 10); | ||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
// RUN: %clangxx_asan -O0 -mllvm -asan-instrument-allocas %s -o %t | ||
// RUN: not %run %t 2>&1 | FileCheck %s | ||
// | ||
|
||
#include <assert.h> | ||
#include <stdint.h> | ||
|
||
void foo(int index, int len) { | ||
for (int i = 1; i < len; ++i) { | ||
char array[len]; // NOLINT | ||
assert(!(reinterpret_cast<uintptr_t>(array) & 31L)); | ||
array[index + i] = 0; | ||
// CHECK: ERROR: AddressSanitizer: dynamic-stack-buffer-overflow on address [[ADDR:0x[0-9a-f]+]] | ||
// CHECK: WRITE of size 1 at [[ADDR]] thread T0 | ||
} | ||
} | ||
|
||
int main(int argc, char **argv) { | ||
foo(9, 21); | ||
return 0; | ||
} |