...
This compliant solution uses a compare-and-exchange to guarantee that the correct value is stored in flag
. All updates are visible to other threads. The call to atomic_compare_exchange_weak()
is in a loop in conformance with .
Code Block | ||||
---|---|---|---|---|
| ||||
#include <stdatomic.h> #include <stdbool.h> static atomic_bool flag = ATOMIC_VAR_INIT(false); void init_flag(void) { atomic_init(&flag, false); } void toggle_flag(void) { bool old_flag = atomic_load(&flag); bool new_flag; do { new_flag = !old_flag; } while (!atomic_compare_exchange_weak(&flag, &old_flag, new_flag)); } bool get_flag(void) { return atomic_load(&flag); } |
An alternative solution is to use the atomic_flag
data type for managing Boolean values atomically. However, atomic_flag
does not support a toggle operation.
Compliant Solution (Compound Assignment)
This compliant solution uses the ^=
assignment operation to toggle flag
. This operation is guaranteed to be atomic, according to the C Standard, 6.5.16.2, paragraph 3. This operation performs a bitwise-exclusive-or between its arguments, but for Boolean arguments, this is equivalent to negation.
Code Block | ||||
---|---|---|---|---|
| ||||
#include <stdatomic.h> #include <stdbool.h> static atomic_bool flag = ATOMIC_VAR_INIT(false); void toggle_flag(void) { flag ^= 1; } bool get_flag(void) { return flag; } |
An alternative solution is to use a mutex to protect the atomic operation, but this solution loses the performance benefits of atomic variables.
Noncompliant Code Example
This noncompliant code example takes an atomic global variable n
and computes n + (n - 1) + (n - 2) + ... + 1
, using the formula n * (n + 1) / 2
:
Code Block | ||||
---|---|---|---|---|
| ||||
#include <stdatomic.h> atomic_int n = ATOMIC_VAR_INIT(0); int compute_sum(void) { return n * (n + 1) / 2; } |
The value of n
may change between the two atomic reads of n
in the expression, yielding an incorrect result.
Compliant Solution
This compliant solution passes the atomic variable as a function argument, forcing the variable to be copied and guaranteeing a correct result. Note that the function's formal parameter need not be atomic, and the atomic variable can still be passed as an actual argument.
Code Block | ||||
---|---|---|---|---|
| ||||
#include <stdatomic.h> int compute_sum(int n) { return n * (n + 1) / 2; } |
Risk Assessment
When operations on atomic variables are assumed to be atomic, but are not atomic, surprising data races can occur, leading to corrupted data and invalid control flow.
Rule | Severity | Likelihood | Remediation Cost | Priority | Level |
---|---|---|---|---|---|
CON40-C | Medium | Probable | Medium | P8 | L2 |
Automated Detection
Tool | Version | Checker | Description | ||||||
---|---|---|---|---|---|---|---|---|---|
Astrée |
| multiple-atomic-accesses | Partially checked | ||||||
Axivion Bauhaus Suite |
| CertC-CON40 | |||||||
CodeSonar |
| CONCURRENCY.MAA | Multiple Accesses of Atomic | ||||||
Coverity |
| EVALUATION_ORDER (partial) MISRA 2012 Rule 13.2 VOLATILE_ATOICITY (possible) | Implemented | ||||||
Helix QAC |
| C1114, C1115, C1116 C++3171, C++4150 | |||||||
Klocwork |
| CERT.CONC.ATOMIC_TWICE_EXPR | |||||||
Parasoft C/C++test |
| CERT_C-CON40-a | Do not refer to an atomic variable twice in an expression | ||||||
Polyspace Bug Finder |
| CERT C: Rule CON40-C | Checks for:
Rule fully covered. | ||||||
PRQA QA-C |
| 1114, 1115, 1116 | |||||||
RuleChecker |
| multiple-atomic-accesses | Partially checked |
Related Vulnerabilities
Search for vulnerabilities resulting from the violation of this rule on the CERT website.
Related Guidelines
Key here (explains table format and definitions)
Taxonomy | Taxonomy item | Relationship |
---|---|---|
CWE 2.11 | CWE-366, Race Condition within a Thread | 2017-07-07: CERT: Rule subset of CWE |
CERT-CWE Mapping Notes
Key here for mapping notes
CWE-366 and CON40-C
CON40-C = Subset( CON43-C) Intersection( CON32-C, CON40-C) = Ø
CWE-366 = Union( CON40-C, list) where list =
- C data races that do not involve an atomic variable used twice within an expression
Bibliography
6.5.16.2, "Compound Assignment" |