xref: /llvm-project/compiler-rt/test/dfsan/libatomic.c (revision 445978ee8c398ddc5d8ae51bc0b0137ce3bb37cb)
1 // RUN: %clang_dfsan -g3 -DDATA_BYTES=3 %s -fno-exceptions %libatomic -o %t && %run %t
2 // RUN: %clang_dfsan -g3 -DDATA_BYTES=3 -DORIGIN_TRACKING -mllvm -dfsan-track-origins=1 %s -fno-exceptions %libatomic -o %t && %run %t
3 // RUN: %clang_dfsan -g3 -DDATA_BYTES=32 %s -fno-exceptions %libatomic -o %t && %run %t
4 // RUN: %clang_dfsan -g3 -DDATA_BYTES=32 -DORIGIN_TRACKING -mllvm -dfsan-track-origins=1 %s -fno-exceptions %libatomic -o %t && %run %t
5 
6 #include <assert.h>
7 #include <sanitizer/dfsan_interface.h>
8 #include <stdatomic.h>
9 
10 typedef struct __attribute((packed)) {
11   uint8_t val[DATA_BYTES];
12 } idata;
13 
test_idata_load()14 void test_idata_load() {
15   idata dest = {-1};
16   idata init = {0};
17 
18   dfsan_label i_label = 2;
19   dfsan_set_label(i_label, &init, sizeof(init));
20 
21   __atomic_load(&init, &dest, __ATOMIC_RELAXED);
22 
23   dfsan_label read_label = dfsan_read_label(&dest, sizeof(dest));
24   assert(read_label == i_label);
25 #ifdef ORIGIN_TRACKING
26   dfsan_origin read_origin =
27       dfsan_read_origin_of_first_taint(&dest, sizeof(dest));
28   assert(read_origin != 0);
29 #endif
30 }
31 
test_idata_store()32 void test_idata_store() {
33   idata dest = {-1};
34   idata init = {0};
35 
36   dfsan_label i_label = 2;
37   dfsan_set_label(i_label, &init, sizeof(init));
38 
39   __atomic_store(&init, &dest, __ATOMIC_RELAXED);
40 
41   dfsan_label read_label = dfsan_read_label(&dest, sizeof(dest));
42   assert(read_label == i_label);
43 #ifdef ORIGIN_TRACKING
44   dfsan_origin read_origin =
45       dfsan_read_origin_of_first_taint(&dest, sizeof(dest));
46   assert(read_origin != 0);
47 #endif
48 }
49 
test_idata_exchange()50 void test_idata_exchange() {
51   idata target = {-1};
52   idata init = {0};
53   idata dest = {3};
54 
55   dfsan_label i_label = 1;
56   dfsan_set_label(i_label, &init, sizeof(init));
57   dfsan_label j_label = 2;
58   dfsan_set_label(j_label, &target, sizeof(target));
59 
60   dfsan_label dest0_label = dfsan_read_label(&dest, sizeof(dest));
61   assert(dest0_label == 0);
62 #ifdef ORIGIN_TRACKING
63   dfsan_origin dest0_origin =
64       dfsan_read_origin_of_first_taint(&dest, sizeof(dest));
65   assert(dest0_origin == 0);
66 #endif
67 
68   __atomic_exchange(&target, &init, &dest, __ATOMIC_RELAXED);
69 
70   dfsan_label dest_label = dfsan_read_label(&dest, sizeof(dest));
71   assert(dest_label == j_label);
72 #ifdef ORIGIN_TRACKING
73   dfsan_origin dest_origin =
74       dfsan_read_origin_of_first_taint(&dest, sizeof(dest));
75   assert(dest_origin != 0);
76 #endif
77 
78   dfsan_label target_label = dfsan_read_label(&target, sizeof(target));
79   assert(target_label == i_label);
80 #ifdef ORIGIN_TRACKING
81   dfsan_origin target_origin =
82       dfsan_read_origin_of_first_taint(&target, sizeof(target));
83   assert(target_origin != 0);
84 #endif
85 }
86 
test_idata_cmp_exchange_1()87 void test_idata_cmp_exchange_1() {
88   idata target = {0};
89   idata expected = {0}; // Target matches expected
90   idata desired = {3};
91 
92   dfsan_label i_label = 1;
93   dfsan_set_label(i_label, &expected, sizeof(expected));
94   dfsan_label j_label = 2;
95   dfsan_set_label(j_label, &target, sizeof(target));
96   dfsan_label k_label = 4;
97   dfsan_set_label(k_label, &desired, sizeof(desired));
98 
99   int r =
100       __atomic_compare_exchange(&target, &expected, &desired, /*weak=false*/ 0,
101                                 __ATOMIC_RELAXED, __ATOMIC_RELAXED);
102   // Target matches expected => true
103   assert(r);
104 
105   // Copy desired to target.
106   dfsan_label target_label = dfsan_read_label(&target, sizeof(target));
107   assert(target_label == k_label);
108 #ifdef ORIGIN_TRACKING
109   dfsan_origin target_origin =
110       dfsan_read_origin_of_first_taint(&target, sizeof(target));
111   assert(target_origin != 0);
112 #endif
113 }
114 
test_idata_cmp_exchange_2()115 void test_idata_cmp_exchange_2() {
116   idata target = {0};
117   idata expected = {-1}; // Target does not match expected
118   idata desired = {3};
119 
120   dfsan_label i_label = 1;
121   dfsan_set_label(i_label, &expected, sizeof(expected));
122   dfsan_label j_label = 2;
123   dfsan_set_label(j_label, &target, sizeof(target));
124   dfsan_label k_label = 4;
125   dfsan_set_label(k_label, &desired, sizeof(desired));
126 
127   int r =
128       __atomic_compare_exchange(&target, &expected, &desired, /*weak=false*/ 0,
129                                 __ATOMIC_RELAXED, __ATOMIC_RELAXED);
130   // Target does not match expected => false
131   assert(!r);
132 
133   // Copy target to expected
134   dfsan_label expected_label = dfsan_read_label(&expected, sizeof(expected));
135   assert(expected_label == j_label);
136 #ifdef ORIGIN_TRACKING
137   dfsan_origin expected_origin =
138       dfsan_read_origin_of_first_taint(&expected, sizeof(expected));
139   assert(expected_origin != 0);
140 #endif
141 }
142 
main()143 int main() {
144   test_idata_load();
145   test_idata_store();
146   test_idata_exchange();
147   test_idata_cmp_exchange_1();
148   test_idata_cmp_exchange_2();
149 
150   return 0;
151 }
152