You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 2 Next »

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)

  • No labels