-
Notifications
You must be signed in to change notification settings - Fork 2k
Expand file tree
/
Copy pathDoubleCheckedLocking.ql
More file actions
41 lines (37 loc) · 1.23 KB
/
DoubleCheckedLocking.ql
File metadata and controls
41 lines (37 loc) · 1.23 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
/**
* @name Double-checked locking is not thread-safe
* @description A repeated check on a non-volatile field is not thread-safe, and
* could result in unexpected behavior.
* @kind problem
* @problem.severity error
* @precision high
* @id java/unsafe-double-checked-locking
* @tags quality
* reliability
* concurrency
* external/cwe/cwe-609
*/
import java
import DoubleCheckedLocking
predicate allFieldsFinal(Class c) { forex(Field f | c.inherits(f) | f.isFinal()) }
predicate immutableFieldType(Type t) {
allFieldsFinal(t) or
t instanceof ImmutableType
}
from IfStmt if1, IfStmt if2, SynchronizedStmt sync, Field f
where
doubleCheckedLocking(if1, if2, sync, f) and
not f.isVolatile() and
not (
// Non-volatile double-checked locking is ok when the object is immutable and
// there is only a single non-synchronized field read.
immutableFieldType(f.getType()) and
1 =
strictcount(FieldAccess fa |
fa.getField() = f and
fa.getEnclosingCallable() = sync.getEnclosingCallable() and
not fa.getEnclosingStmt().getEnclosingStmt*() = sync.getBlock()
)
)
select sync, "Double-checked locking on the non-volatile field $@ is not thread-safe.", f,
f.toString()