39 lines
2.7 KiB
Markdown
39 lines
2.7 KiB
Markdown
# UNDF: UNDF-2026-000000405
|
||
# GraalVM CWE-407 Scan — CLEAN
|
||
|
||
**Repo:** `https://github.com/oracle/graal` (depth=1, tag: main)
|
||
**Scan date:** 2026-03-27
|
||
**Scope:** `compiler/src/jdk.graal.compiler/` + `truffle/src/`
|
||
|
||
## Method
|
||
|
||
Searched for `ArrayList`/`List` fields combined with `.contains()` calls
|
||
across all non-test Java sources. Each candidate was manually triaged for
|
||
an outer loop that elevates the linear scan to super-linear complexity.
|
||
|
||
## Candidates reviewed
|
||
|
||
| File | Line | Pattern | Verdict |
|
||
|------|------|---------|---------|
|
||
| `lir/alloc/lsra/RegisterVerifier.java` | 73 | `workList.contains(block)` — ArrayList worklist dedup | **Debug-only** — gated by `isDetailedAsserts()` in `LinearScan.verify()`. Not on production hot path. |
|
||
| `lir/alloc/lsra/MoveResolver.java` | 374 | `busySpillSlots.contains(...)` — ArrayList(capacity=2) | **Bounded** — `busySpillSlots` holds spill slots in a single cycle-break pass; practical max ≈ 4. |
|
||
| `lir/amd64/phases/StackMoveOptimizationPhase.java` | 114 | `dst.contains(in)` inside instruction trace | **Bounded** — `dst` is the destination list for one StackMoveOp trace; traces are typically 2–6 moves. |
|
||
| `replacements/DefaultJavaLoweringProvider.java` | 1113 | `newList.contains(lock)` inside `getLocks()` loop | **Bounded** — `getLocks()` is the monitor-enter list for one `CommitAllocationNode`; practical nesting depth ≤ 8. |
|
||
| `java/BciBlockMapping.java` | 1528 | `jsrVisited.contains(successor)` | **Rare path** — JSR/RET bytecodes are deprecated since Java 7; generated only by very old compilers. |
|
||
| `truffle/host/HostInliningPhase.java` | 538,611,686 | `unwindBlocks.contains(...)` | **Clean** — `unwindBlocks` is `EconomicSet` (O(1) hash lookup). |
|
||
| `virtual/phases/ea/PartialEscapeClosure.java` | 1533 | `state.contains(virtualObjs[v])` | **Structural** — `state.contains()` is O(O×E); outer loop is over phi predecessors (typically 2–4). Not a dedup membership scan. No O(N²) growth. |
|
||
| `nodes/calc/BinaryArithmeticNode.java` | 169,200 | `Arrays.asList(...).contains(op)` | **Error path only** — leads to `GraalError.unimplemented()`. Never reached in normal compilation. |
|
||
|
||
## Conclusion
|
||
|
||
**GraalVM compiler: CLEAN** — no CWE-407 defects found on production hot paths.
|
||
|
||
All `ArrayList.contains()` sites are either:
|
||
- Gated by debug/assert flags
|
||
- Bounded to very small collections (≤ 8 elements) by structural invariants
|
||
- On error-handling paths unreachable in normal operation
|
||
- Using `EconomicSet` / `NodeBitMap` (O(1)) rather than linear-scan containers
|
||
|
||
The Graal graph node infrastructure consistently uses `EconomicSet`,
|
||
`NodeBitMap`, and indexed arrays for hot-path membership tests — the same
|
||
O(1) patterns we recommend in CWE-407 fixes.
|