Declaring an immutable or thread-safe object as volatile ensures that a thread will not observe the object in an inconsistent state prior to its initialization. However, declaring mutable or thread-unsafe objects volatile does not offer any such advantages.
Noncompliant Code Example
This noncompliant code example declares an instance field of type Date as volatile. The problem is that the field can be changed using a setter method setDate(). Even if one thread sees the new reference, the object state that it observes may change in the meantime.
public class Foo {
public volatile Date d;
public Foo() {
d = new Date();
}
public void setDate(Date date) {
d = date;
}
public Date getDate() {
return d;
}
}
public class Client {
public void doSomething() {
Foo f = new Foo();
if (f.d != null) {
// ...
}
}
}
The client code depends on the publication of the Date object to carry out its operations. There is a race condition between setting the date and checking in the client code, whether it is null. During the race window interval, the state of the Date object could change.
Compliant Solution
The object can only be safely published if it is immutable or thread-safe. Otherwise, explicit synchronization is required to ensure thread safety. This compliant solution uses volatile to guard retrievals that use the getter method. A synchronized setter method is used to set the value of the Date object to ensure thread-safety. Defensive copies of the setter argument must be made to make the class Foo effectively immutable.
public class Foo {
public volatile Date d;
public Foo() {
d = new Date();
}
public synchronized void setDate(Date date) {
// Defensive copying
d = date.clone();
}
public Date getDate() {
return d.clone();
}
}
Compliant Solution
This compliant solution ensures that the Foo object is immutable by removing the setter method. The Date object can be safely published as a result.
public class Foo {
public final Date d;
public Foo() {
d = new Date();
}
public Date getDate() {
return d;
}
}
Risk Assessment
Rule |
Severity |
Likelihood |
Remediation Cost |
Priority |
Level |
|---|---|---|---|---|---|
CON26- J |
medium |
probable |
medium |
P12 |
L1 |
Automated Detection
TODO
Related Vulnerabilities
Search for vulnerabilities resulting from the violation of this rule on the CERT website.
References
[[Goetz 07]] Pattern #2: "one-time safe publication"
FIO36-J. Do not create multiple buffered wrappers on an InputStream 09. Input Output (FIO) 09. Input Output (FIO)