DFSan at store does store shadow data; store app data; and at load does
load shadow data; load app data.
When an application data is atomic, one overtainting case is
thread A: load shadow thread B: store shadow thread B: store app thread A: load app
If the application address had been used by other flows, thread A reads
previous shadow, causing overtainting.
The change is similar to MSan's solution.
- enforce ordering of app load/store
- load shadow after load app; store shadow before shadow app
- do not track atomic store by reseting its shadow to be 0.
The last one is to address a case like this.
Thread A: load app Thread B: store shadow Thread A: load shadow Thread B: store app
This approach eliminates overtainting as a trade-off between undertainting
flows via shadow data race.
Note that this change addresses only native atomic instructions, but
does not support builtin atomic libcalls yet.
Should we also test builtin atomics? https://gcc.gnu.org/onlinedocs/gcc/_005f_005fatomic-Builtins.html