Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: the usual edits, promoting to draft

...

Wiki Markup
The _private lock object_ idiom can be used to prevent this vulnerability. The idiom consists of a raw {{java.lang.Object}} declared within the class as {{private}} and {{final}}. The object must be explicitly used for locking purposes in {{synchronized}} blocks, within the class's methods. This intrinsic lock is associated with the instance of the internal private object and not with the class itself. Consequently, there is no lock contention between this class's methods and methods of a hostile class. \[[Bloch 01|AA. Java References#Bloch 01]\] 

Static state has the same potential problem. If a static method is declared synchronized, the intrinsic lock of the Class class object is acquired before executing the statements in its body, and released when the method completes. Any untrusted code that can access an object of the class, or a subclass, can use the getClass() method to gain access to the Class class object. The private lock object idiom can be used to protect static data by declaring the lock as private, static and final. Reducing the accessibility of the class to package-private may offer some reprieve from untrusted callers when using strategies other than internal locking.

...

  • subclass the class or its superclass (trusted code is allowed to subclass the class)
  • create an object of the class (or its superclass, or subclass)
  • access or acquire an object instance of the class (or its superclass, or subclass)

If a superclass class uses an internal private lock to synchronize shared data, subclasses must also use an internal private lock. However, if a class uses intrinsic synchronization over the class object without documenting its locking policy, subclasses may not use intrinsic synchronization over their own class object, unless they explicitly document their locking policy. If the superclass documents its policy by stating that client-side locking is supported, the subclasses have the option of choosing between intrinsic locking over the class object and an internal private lock. Regardless of what is chosen, subclasses must document their locking policy. Refer to the guideline CON10-J. Do not override thread-safe methods with methods that are not thread-safe for related information.

If these restrictions are not met, the object's intrinsic lock is not trustworthy. If all conditions are satisfied, then the object gains no significant security from using a an internal private internal lock object, and may synchronize using its own intrinsic lock.

...

Any thread can modify the field's value to refer to some other object in the presence of an accessor such as setLock(). This might cause two threads that intend to lock on the same object to lock on different objects, enabling them to execute the two critical sections in an unsafe manner. For example, if one thread is in its critical section and the lock is changed, a second thread would will lock on the new reference instead of the old one.

Compliant Solution (internal private final

...

lock object)

Thread-safe classes that use the intrinsic synchronization of their respective objects may be protected by using the private lock object idiom and refactoring them to use block synchronization. In this compliant solution, if the method changeValue() is called, the lock is obtained on a private final Object instance that is inaccessible from the callercallers that exist outside the class's scope.

Code Block
bgColor#ccccff
public class SomeObject {
  private final Object lock = new Object(); // private lock object

  public void changeValue() {
    synchronized (lock) { // Locks on the private Object
      // ...
    }
  }
}

A private final lock can only be used with block synchronization. Block synchronization is preferred over method synchronization, because operations that do not require synchronization can be moved outside the synchronized region, reducing the overall execution timelock contention and blocking. Note that there is no need to declare lock as volatile because of the strong visibility semantics of final fields. Instead of using setter methods to change the lock, declare and use multiple internal lock objects to meet the required locking granularity objectives.

...

Thread-safe classes that use intrinsic synchronization over the class object should be refactored to use a static internal private internal lock object and block synchronization.

...