Skip to content

Commit

Permalink
[dfsan] Add test cases for struct/pair
Browse files Browse the repository at this point in the history
This is a child diff of D92261.

This locks down the behavior before the change.
  • Loading branch information
stephan-yichao-zhao committed Dec 2, 2020
1 parent ee571f8 commit 6fa0662
Show file tree
Hide file tree
Showing 2 changed files with 215 additions and 0 deletions.
138 changes: 138 additions & 0 deletions compiler-rt/test/dfsan/pair.cpp
@@ -0,0 +1,138 @@
// RUN: %clangxx_dfsan %s -mllvm -dfsan-fast-16-labels -mllvm -dfsan-track-select-control-flow=false -mllvm -dfsan-combine-pointer-labels-on-load=false -o %t && %run %t

#include <algorithm>
#include <assert.h>
#include <sanitizer/dfsan_interface.h>
#include <utility>

__attribute__((noinline))
std::pair<int *, int>
make_pair(int *p, int i) { return {p, i}; }

__attribute__((noinline))
std::pair<int *, int>
copy_pair1(const std::pair<int *, int> &pair) {
return pair;
}

__attribute__((noinline))
std::pair<int *, int>
copy_pair2(std::pair<int *, int> *pair) {
return *pair;
}

__attribute__((noinline))
std::pair<int *, int>
copy_pair3(std::pair<int *, int> &&pair) {
return std::move(pair);
}

__attribute__((noinline))
std::pair<const char *, uint32_t>
return_ptr_and_i32(const char *p, uint32_t res) {
for (uint32_t i = 2; i < 5; i++) {
uint32_t byte = static_cast<uint8_t>(p[i]);
res += (byte - 1) << (7 * i);
if (byte < 128) {
return {p + i + 1, res};
}
}
return {nullptr, 0};
}

__attribute__((noinline))
std::pair<const char *, uint64_t>
return_ptr_and_i64(const char *p, uint32_t res32) {
uint64_t res = res32;
for (uint32_t i = 2; i < 10; i++) {
uint64_t byte = static_cast<uint8_t>(p[i]);
res += (byte - 1) << (7 * i);
if (byte < 128) {
return {p + i + 1, res};
}
}
return {nullptr, 0};
}

void test_simple_constructors() {
int i = 1;
int *ptr = NULL;
dfsan_set_label(8, &i, sizeof(i));
dfsan_set_label(2, &ptr, sizeof(ptr));

std::pair<int *, int> pair1 = make_pair(ptr, i);
int i1 = pair1.second;
int *ptr1 = pair1.first;

assert(dfsan_read_label(&i1, sizeof(i1)) == 10);
assert(dfsan_read_label(&ptr1, sizeof(ptr1)) == 10);

std::pair<int *, int> pair2 = copy_pair1(pair1);
int i2 = pair2.second;
int *ptr2 = pair2.first;

assert(dfsan_read_label(&i2, sizeof(i2)) == 10);
assert(dfsan_read_label(&ptr2, sizeof(ptr2)) == 10);

std::pair<int *, int> pair3 = copy_pair2(&pair1);
int i3 = pair3.second;
int *ptr3 = pair3.first;

assert(dfsan_read_label(&i3, sizeof(i3)) == 10);
assert(dfsan_read_label(&ptr3, sizeof(ptr3)) == 10);

std::pair<int *, int> pair4 = copy_pair3(std::move(pair1));
int i4 = pair4.second;
int *ptr4 = pair4.first;

assert(dfsan_read_label(&i4, sizeof(i4)) == 10);
assert(dfsan_read_label(&ptr4, sizeof(ptr4)) == 10);
}

void test_branches() {
uint32_t res = 4;
dfsan_set_label(8, &res, sizeof(res));

char p[100];
const char *q = p;
dfsan_set_label(2, &q, sizeof(q));

{
std::fill_n(p, 100, static_cast<char>(128));

{
std::pair<const char *, uint32_t> r = return_ptr_and_i32(q, res);
assert(dfsan_read_label(&r.first, sizeof(r.first)) == 0);
assert(dfsan_read_label(&r.second, sizeof(r.second)) == 0);
}

{
std::pair<const char *, uint64_t> r = return_ptr_and_i64(q, res);
assert(dfsan_read_label(&r.first, sizeof(r.first)) == 0);
assert(dfsan_read_label(&r.second, sizeof(r.second)) == 0);
}
}

{
std::fill_n(p, 100, 0);

{
std::pair<const char *, uint32_t> r = return_ptr_and_i32(q, res);
assert(dfsan_read_label(&r.first, sizeof(r.first)) == 10);
assert(dfsan_read_label(&r.second, sizeof(r.second)) == 10);
}

{
std::pair<const char *, uint64_t> r = return_ptr_and_i64(q, res);
assert(dfsan_read_label(&r.first, sizeof(r.first)) == 10);
assert(dfsan_read_label(&r.second, sizeof(r.second)) == 10);
}
}
}

int main(void) {
test_simple_constructors();
test_branches();

return 0;
}
77 changes: 77 additions & 0 deletions compiler-rt/test/dfsan/struct.c
@@ -0,0 +1,77 @@
// RUN: %clang_dfsan %s -o %t && %run %t

#include <assert.h>
#include <sanitizer/dfsan_interface.h>

typedef struct Pair {
int i;
char *ptr;
} Pair;

__attribute__((noinline))
Pair make_pair(int i, char *ptr) {
Pair pair;
pair.i = i;
pair.ptr = ptr;
return pair;
}

__attribute__((noinline))
Pair copy_pair1(const Pair *pair0) {
Pair pair;
pair.i = pair0->i;
pair.ptr = pair0->ptr;
return pair;
}

__attribute__((noinline))
Pair copy_pair2(const Pair pair0) {
Pair pair;
pair.i = pair0.i;
pair.ptr = pair0.ptr;
return pair;
}

int main(void) {
int i = 1;
char *ptr = NULL;
dfsan_label i_label = dfsan_create_label("i", 0);
dfsan_set_label(i_label, &i, sizeof(i));
dfsan_label ptr_label = dfsan_create_label("ptr", 0);
dfsan_set_label(ptr_label, &ptr, sizeof(ptr));

Pair pair1 = make_pair(i, ptr);
int i1 = pair1.i;
char *ptr1 = pair1.ptr;

dfsan_label i1_label = dfsan_read_label(&i1, sizeof(i1));
dfsan_label ptr1_label = dfsan_read_label(&ptr1, sizeof(ptr1));
assert(dfsan_has_label(i1_label, i_label));
assert(dfsan_has_label(i1_label, ptr_label));
assert(dfsan_has_label(ptr1_label, i_label));
assert(dfsan_has_label(ptr1_label, ptr_label));

Pair pair2 = copy_pair1(&pair1);
int i2 = pair2.i;
char *ptr2 = pair2.ptr;

dfsan_label i2_label = dfsan_read_label(&i2, sizeof(i2));
dfsan_label ptr2_label = dfsan_read_label(&ptr2, sizeof(ptr2));
assert(dfsan_has_label(i2_label, i_label));
assert(dfsan_has_label(i2_label, ptr_label));
assert(dfsan_has_label(ptr2_label, i_label));
assert(dfsan_has_label(ptr2_label, ptr_label));

Pair pair3 = copy_pair2(pair1);
int i3 = pair3.i;
char *ptr3 = pair3.ptr;

dfsan_label i3_label = dfsan_read_label(&i3, sizeof(i3));
dfsan_label ptr3_label = dfsan_read_label(&ptr3, sizeof(ptr3));
assert(dfsan_has_label(i3_label, i_label));
assert(dfsan_has_label(i3_label, ptr_label));
assert(dfsan_has_label(ptr3_label, i_label));
assert(dfsan_has_label(ptr3_label, ptr_label));

return 0;
}

0 comments on commit 6fa0662

Please sign in to comment.