// RUN: %clang_dfsan -g3 -DDATA_BYTES=3 %s -fno-exceptions %libatomic -o %t && %run %t // RUN: %clang_dfsan -g3 -DDATA_BYTES=3 -DORIGIN_TRACKING -mllvm -dfsan-track-origins=1 %s -fno-exceptions %libatomic -o %t && %run %t // RUN: %clang_dfsan -g3 -DDATA_BYTES=32 %s -fno-exceptions %libatomic -o %t && %run %t // RUN: %clang_dfsan -g3 -DDATA_BYTES=32 -DORIGIN_TRACKING -mllvm -dfsan-track-origins=1 %s -fno-exceptions %libatomic -o %t && %run %t #include #include #include typedef struct __attribute((packed)) { uint8_t val[DATA_BYTES]; } idata; void test_idata_load() { idata dest = {-1}; idata init = {0}; dfsan_label i_label = 2; dfsan_set_label(i_label, &init, sizeof(init)); __atomic_load(&init, &dest, __ATOMIC_RELAXED); dfsan_label read_label = dfsan_read_label(&dest, sizeof(dest)); assert(read_label == i_label); #ifdef ORIGIN_TRACKING dfsan_origin read_origin = dfsan_read_origin_of_first_taint(&dest, sizeof(dest)); assert(read_origin != 0); #endif } void test_idata_store() { idata dest = {-1}; idata init = {0}; dfsan_label i_label = 2; dfsan_set_label(i_label, &init, sizeof(init)); __atomic_store(&init, &dest, __ATOMIC_RELAXED); dfsan_label read_label = dfsan_read_label(&dest, sizeof(dest)); assert(read_label == i_label); #ifdef ORIGIN_TRACKING dfsan_origin read_origin = dfsan_read_origin_of_first_taint(&dest, sizeof(dest)); assert(read_origin != 0); #endif } void test_idata_exchange() { idata target = {-1}; idata init = {0}; idata dest = {3}; dfsan_label i_label = 1; dfsan_set_label(i_label, &init, sizeof(init)); dfsan_label j_label = 2; dfsan_set_label(j_label, &target, sizeof(target)); dfsan_label dest0_label = dfsan_read_label(&dest, sizeof(dest)); assert(dest0_label == 0); #ifdef ORIGIN_TRACKING dfsan_origin dest0_origin = dfsan_read_origin_of_first_taint(&dest, sizeof(dest)); assert(dest0_origin == 0); #endif __atomic_exchange(&target, &init, &dest, __ATOMIC_RELAXED); dfsan_label dest_label = dfsan_read_label(&dest, sizeof(dest)); assert(dest_label == j_label); #ifdef ORIGIN_TRACKING dfsan_origin dest_origin = dfsan_read_origin_of_first_taint(&dest, sizeof(dest)); assert(dest_origin != 0); #endif dfsan_label target_label = dfsan_read_label(&target, sizeof(target)); assert(target_label == i_label); #ifdef ORIGIN_TRACKING dfsan_origin target_origin = dfsan_read_origin_of_first_taint(&target, sizeof(target)); assert(target_origin != 0); #endif } void test_idata_cmp_exchange_1() { idata target = {0}; idata expected = {0}; // Target matches expected idata desired = {3}; dfsan_label i_label = 1; dfsan_set_label(i_label, &expected, sizeof(expected)); dfsan_label j_label = 2; dfsan_set_label(j_label, &target, sizeof(target)); dfsan_label k_label = 4; dfsan_set_label(k_label, &desired, sizeof(desired)); int r = __atomic_compare_exchange(&target, &expected, &desired, /*weak=false*/ 0, __ATOMIC_RELAXED, __ATOMIC_RELAXED); // Target matches expected => true assert(r); // Copy desired to target. dfsan_label target_label = dfsan_read_label(&target, sizeof(target)); assert(target_label == k_label); #ifdef ORIGIN_TRACKING dfsan_origin target_origin = dfsan_read_origin_of_first_taint(&target, sizeof(target)); assert(target_origin != 0); #endif } void test_idata_cmp_exchange_2() { idata target = {0}; idata expected = {-1}; // Target does not match expected idata desired = {3}; dfsan_label i_label = 1; dfsan_set_label(i_label, &expected, sizeof(expected)); dfsan_label j_label = 2; dfsan_set_label(j_label, &target, sizeof(target)); dfsan_label k_label = 4; dfsan_set_label(k_label, &desired, sizeof(desired)); int r = __atomic_compare_exchange(&target, &expected, &desired, /*weak=false*/ 0, __ATOMIC_RELAXED, __ATOMIC_RELAXED); // Target does not match expected => false assert(!r); // Copy target to expected dfsan_label expected_label = dfsan_read_label(&expected, sizeof(expected)); assert(expected_label == j_label); #ifdef ORIGIN_TRACKING dfsan_origin expected_origin = dfsan_read_origin_of_first_taint(&expected, sizeof(expected)); assert(expected_origin != 0); #endif } int main() { test_idata_load(); test_idata_store(); test_idata_exchange(); test_idata_cmp_exchange_1(); test_idata_cmp_exchange_2(); return 0; }