False Negative: DoubleCheckedLockingWithInitRace.ql misses initialization races once the double-checked pattern is split across helpers or early returns.
- Langage dominant
- CodeQL
- Étoiles
- 10.1k
- Forks
- 2.1k
- Merge moyen
- 2 j 15 h
- PR mergées (30 j)
- 141
Description
# False Negative: DoubleCheckedLockingWithInitRace.ql misses initialization races once the double-checked pattern is split across helpers or early returns.
Version
codeql 2.24.3
## Checker
- Checker id: `Likely Bugs/Concurrency/DoubleCheckedLockingWithInitRace.ql`
- Checker description: This checker detects a potential race condition in double-checked locking patterns where a field assignment inside a synchronized block may be visible to other threads before subsequent side-effect statements are executed.
## Description of the false negative
These samples still publish `f` before the rest of the initialization work is complete. One variant moves the synchronized initialization into a helper, and the other rewrites the fast path as an early return, but the initialization race is the same.
## Affected test cases
### `PosCase1_Var3.java`
The helper call only hides the same double-checked-locking race where publication happens before later side effects.
```java
// Double-checked locking with assignment to another field after the field assignment should be flagged as potential race condition.
package scensct.var.pos;
public class PosCase1_Var3 {
private Object f;
private Object otherField;
public Object getF() {
if (f == null) {
initField();
}
return f;
}
private void initField() {
synchronized (this) {
if (f == null) {
f = new Object();
otherField = new Object();
}
}
}
}
```
### `PosCase1_Var5.java`
This still publishes the initialized object before a later field assignment completes, which is the race the query is meant to catch.
```java
// Double-checked locking with assignment to another field after the field assignment should be flagged as potential race condition.
package scensct.var.pos;
public class PosCase1_Var5 {
private Object f;
private Object otherField;
public Object getF() {
if (f != null) {
return f;
}
synchronized (this) {
if (f == null) {
f = new Object();
otherField = new Object();
}
return f;
}
}
}
```
## Cause analysis
The query appears too tied to one inline statement ordering pattern for double-checked initialization. Once the synchronized block is extracted into a helper or the fast path is expressed as an early return, it stops recognizing that `f` becomes visible before the remaining side effects complete.
That is a real concurrency gap. Initialization races often survive exactly this kind of refactoring.
## References
None known.
Guide de contribution
Ouvrir le guide de contribution
Piste de recherche
Commencez par lire Likely Bugs/Concurrency/DoubleCheckedLockingWithInitRace.ql ainsi que les exemples PosCase1_Var3.java et PosCase1_Var5.java. Suivez la manière dont la requête gère les appels auxiliaires et les retours anticipés, puis vérifiez que les deux variantes de la condition de concurrence lors de l'initialisation sont signalées.
Rédigé par le modèle d'indexation à partir du texte de l'issue.
Évaluation
- Stack technique
- java
- Domaine
- devtools, security
- Type d'issue
- Bug
- Difficulté
- 4/5
- Temps estimé
- 3-5 jours
- Activité
- Calme
- Clarté
- Plutôt claire
- Accessibilité débutants
- 52/100