The synchronized
keyword is used to acquire a mutual-exclusion lock so that no other thread can acquire the lock ; that is, a lock that cannot be acquired by any other thread while it is being held by the executing thread. There are two ways to synchronize access to shared mutable variables: method synchronization and block synchronization.
A method Both methods declared as synchronized always uses and blocks that synchronize on the this
reference use the objectâs monitor (intrinsic lock), as does code that synchronizes on the this
reference using a synchronized block. Poorly synchronized code is prone to contention and deadlock. An attacker can manipulate the system to trigger these conditions and cause a denial of service contention and deadlock by obtaining and indefinitely holding the intrinsic lock of an accessible class, consequently causing a denial of service.
Wiki Markup |
---|
ThisOne technique for preventing this vulnerability is canthe beâprivate preventedlock usingobjectâ aidiom {{java.lang.Object}} declared\[[Bloch 2001|AA. Bibliography#Bloch 01]\]. This idiom uses the intrinsic lock associated with the instance of a {{private}} and{{final}} {{finaljava.lang.Object}} declared within the class. Thein objectplace mustof bethe usedintrinsic explicitly for locking purposes in synchronized blocks withinlock of the classâsobject methodsitself. This intrinsicidiom lockrequires isthe associateduse withof thesynchronized instanceblocks ofwithin the privateclassâs objectmethods andrather notthan the class.use Consequently,of theresynchronized ismethods. noLock lock contention between thisthe classâs methods and the methodsthose of a hostile class. Blochis refersimpossible, tobecause thisthe techniquehostile asclass thecannot âprivateaccess lock objectâ idiom \[[Bloch 2001|AA. Bibliography#Bloch 01]\].the {{private}} {{final}} lock object. |
Static methods and state also share this vulnerability. When Static state has the same potential problem. If a static method is declared synchronized, it acquires the intrinsic lock of the class object is acquired before any statements in its body are executed, and releases the intrinsic lock is released when the method completes. Any untrusted Untrusted code that can has access to an object of the class, or of a subclass, can use the getClass()
method to gain access to the class object, and consequently to its intrinsic lock. Static Protect static data can be protected by locking on a private static final Object
. Reducing the accessibility of the class to package-private adds further protection against untrusted callers.
This The private lock object idiom is also suitable for classes that are designed for inheritance. If When a superclass thread requests a lock on the objectâs monitor, a subclass thread can interfere with its operation. For example, a subclass may use the superclass objectâs intrinsic lock for performing unrelated operations, caus-ing significant lock contention and deadlock. Separating the locking strategy of the superclass from that of the subclass ensures that they do not share a common lock. It , and also permits fine-grained locking because by supporting the use of multiple lock objects can be used for unrelated operations, increasing . This increases the overall responsiveness of the application.
An object should use a private final Objects that require synchronization must use the private lock object idiom rather than its their own intrinsic lock unless the class can guarantee that in any case where untrusted code cannotcould:
- subclass Subclass the class or its superclass (. Note that trusted code is allowed permitted to subclass the class).
- create Create an object of the class, its superclass, or subclass
- access Access or acquire an object instance of the class, its superclass, or subclass
If a class uses a private final lock to synchronize shared data, subclasses must also use a private final lock. However, if Subclasses whose parents use the private lock object idiom must themselves use the idiom. However, when a class uses intrinsic synchronization over the class object without documenting its locking policy, subclasses may not are forbidden to use intrinsic synchronization over their own class object, unless they explicitly document their locking policy. If When the superclass documents its policy by stating that client-side locking is supported, the subclasses have the option of choosing to choose between intrinsic locking over the class object and a or use of the private lock . Regardless of which is chosen, subclasses object idiom. Subclasses must document their locking policy regardless of which locking option is chosen. See rule TSM00-J. Do not override thread-safe methods with methods that are not thread-safe for related information.
If all of these restrictions are not metWhen any of the above restrictions is violated, the objectâs intrinsic lock is not trustworthy. If they are met, the object gains no significant security from using a private final lock object and may synchronize using its cannot be trusted. When the restrictions are obeyed, the private lock object idiom fails to add additional security. Consequently, objects that comply with all of the above restrictions are permitted to synchronize using their own intrinsic lock. However, it is still best to use block synchronization with a using the private final lock object instead of method synchronization when the method contains idiom is superior to method synchronization for methods that contain non-atomic operations that either do not require any synchronization or can use a more fine-grained locking scheme involving multiple private final lock objects or that lack a requirement for synchronization. Non-atomic operations can be decoupled from those that require synchronization and can be executed outside the synchronized block. For Both for this reason and maintainability reasonsalso for simplification of maintenance, block synchronization using a the private final lock object idiom is generally recommended.
...
Any thread can modify the fieldâs value to refer to a different object in the presence of an accessor such as setLock()
. That modification might cause two threads that intend to lock on the same object to lock on different objects, thereby enabling them to execute the two critical sections in an unsafe manner. For example, if when one thread is in its critical section and the lock is changed, a second thread will lock on the new object instead of the old one.
A class that does not provide any lacks accessible methods to change the lock is secure against untrusted manipulation. However, it is remains susceptible to inadvertent modification by the programmer. For maintainability reasons, eliminating the accessor method (which is presumably needed for other reasons) is not the preferred solution.
...
A private final lock object can only be used with block synchronization. Block synchronization is preferred over method synchronization, because operations that do not require without a requirement for synchronization can be moved outside the synchronized region, reducing lock contention and blocking. Note that there it is no need unnecessary to declare lock
volatile because of the strong visibility semantics of final fields. Instead of using setter methods to change the lockWhen granularity issues require the use of multiple locks, declare and use multiple , private final lock objects to satisfy the granularity requirements rather than using a mutable reference to a lock object along with a setter method.
Noncompliant Code Example (Static)
...
Thread-safe public classes that may interact with untrusted code and both use intrinsic synchronization over the class object and also may interact with untrusted code, must be refactored to use a static private final lock object and block synchronization.
...
LCK00-EX1: A class may violate this rule , if when all of the following conditions are met:
- It sufficiently documents that callers must not are forbidden to pass objects of this class to untrusted code.
- The class does not cannot invoke methods on objects of any untrusted classes that violate this guide-line, whether directly or indirectly.
- The synchronization policy of the class is documented properly.
A client may Clients are permitted to use a class that violates this rule , if when all of the following conditions are met:
- The class does not pass objects of this Neither the client class nor any other class in the system passes objects of the violating class to untrusted code.
- The class does not use any violating class cannot invoke methods from untrusted classes that violate this rule, whether directly or indirectly.
LCK00-EX2: If When a superclass of the class documents that it supports client-side locking and synchronizes on its class object, the class can support client-side locking in the same way and document this policy.
LCK00-EX3: A packagePackage-private class may violate classes are exempt from this rule because its their accessibility protects against untrusted callers. However, use of this condition exemption should be documented explicitly so to ensure that trusted code within the same package does not reuse or change neither reuses the lock object nor changes the lock object inadvertently.
Risk Assessment
Exposing the class lock object to untrusted code can result in denial of service.
...