...
The getSum()
method may return a different sum every time it is invoked from different threads. For instance, if a
and b
currently have the value 0, and one thread calls getSum()
while another calls setValues(1, 1)
, then getSum()
might return 0, 1, or 2. Of these, the value 1 is unacceptable; it is returned when the first thread reads a
and b
, after the second thread has set the value of a
but before it has set the value of b
.
This code also does nothing to prevent arithmetic Note that declaring the variables as volatile
does not resolve the issue. Also, this code does not prevent integer overflow. See INT00-J. Perform explicit range checking to ensure integer operations do not overflow for more information.
...
The issues described in the previous noncompliant code example can also arise even when the variables fields a
and b
of type int
are replaced with atomic integers.
...
For example, when a thread is executing setValues()
another may invoke getSum()
and retrieve an incorrect result. Furthermore, in the absence of synchronization, there are data races in the check for integer overflow. For instance, a thread can call setValues()
after a second thread has read a
, but before it has read b
in order to add them together; in which case, the second thread will get an improper addition. Even worse, a thread can call setValues()
after a second thread has verified that overflow will not occur, but before the second thread reads the values to add. This would cause the second thread to add two values that have not been checked for overflow, and overflow when adding them.
Note that even though a check for integer overflow is installed, there is a time-of-check-time-of-use (TOCTOU) condition between the overflow check and the addition operation.
Compliant Solution (addition, synchronized)
...
Unlike the noncompliant code example, if a
and b
currently have the value 0, and one thread calls getSum()
while another calls setValues(1, 1)
, getSum()
may return return 0, or 2, depending on which thread obtains the intrinsic lock first. The locking guarantees that getSum()
will never return the unacceptable value 1.
This compliant solution also ensures that there is no TOCTOU condition between checking for overflow and adding the fields.
Risk Assessment
If operations on shared variables are not atomic, unexpected results may be produced. For example, there can be inadvertent information disclosure as one user may be able to receive information about other users.
...