The Java Language Specification allows 64-bit long
and double
values to be treated as two 32-bit values. For example, a 64-bit write operation may be performed as two separate 32-bit operations.
Wiki Markup |
---|
According to the Java Language Specification \[[JLS 05|AA. Java References#JLS 05]\], sectionSection 17.7 "Non-atomicAtomic Treatment of {{double}} and {{long}}": |
... this behavior is implementation specific; Java virtual machines are free to perform writes to
long
anddouble
values atomically or in two parts. For the purposes of the Java programming language memory model, a single write to a non-volatilelong
ordouble
value is treated as two separate writes: one to each 32-bit half. This can result in a situation where a thread sees the first 32 bits of a 64 bit value from one write, and the second 32 bits from another write.
This behavior can result in reading indeterminate values being read in code that is required to be thread-safe.
...
In this noncompliant code example, if one thread repeatedly calls the method assignValue()
, method and another thread repeatedly calls the method printLong()
method, then method the printLong()
method could occasionally print a value of i
that is neither zero nor the value of the j
argument j
.
Code Block | ||
---|---|---|
| ||
class LongContainer { private long i = 0; void assignValue(long j) { i = j; } void printLong() { System.out.println("i = " + i); } } |
A similar problem may occur if i
is declared as a double
.
Compliant Solution (
...
Volatile)
This compliant solution declares i
as volatile. Writes and reads of volatile long
and double
volatile values are always atomic.
...
It is important to ensure that the argument to method the assignValue()
method is obtained from a volatile
variable or as a result of explicitly passing an integer value. Otherwise, a read of the variable argument may, itself, expose a vulnerability.
Semantics of volatile
do not guarantee the atomicity of compound operations that involve read-modify-write sequences such as incrementing a value. See CON01-J. Ensure that compound operations on shared variables are atomic for more information.
...
CON25-EX1: If all reads and writes of 64-bit long
and double
values occur within a synchronized region, the atomicity of the read/write is guaranteed. This requires that no unsynchronized methods in the class expose the value and that the value is inaccessible (directly or indirectly) from other code. (For more information, see CON01-J. Ensure that compound operations on shared variables are atomic.)
CON25-EX2: Systems that guarantee that 64-bit long
and double
values are read and written as atomic operations may safely ignore this guideline.
...
Failure to ensure the atomicity of operations involving 64-bit values in multi-threaded multithreaded applications can result in reading and writing indeterminate values. Many Java Virtual Machines (JVMs) read and write 64-bit values atomically, even though the specification does not require them to.
...
TODO
Related Vulnerabilities
Search for Any vulnerabilities resulting from the violation of this rule are listed on the CERT website.
References
Wiki Markup |
---|
\[[JLS 05|AA. Java References#JLS 05]\] 17.7 Non-atomicAtomic Treatment of double and long \[[Goetz 06|AA. Java References#Goetz 06]\] 3.1.2. NonatomicNon-Atomic 64-bitBit Operations \[[Goetz 0404c|AA. Java References#Goetz 0404c]\] Brian Goetz. Java theory and practice: Going atomic. November 2004. http://www.ibm.com/developerworks/java/library/j-jtp11234/ \[[MITRE 09|AA. Java References#MITRE 09]\] [CWE ID 667|http://cwe.mitre.org/data/definitions/667.html] "Insufficient Locking" |
...