undf: assign 768-770; stamp minio patches
This commit is contained in:
parent
cb853893e5
commit
79a77db4f8
28 changed files with 176 additions and 18 deletions
|
|
@ -765,5 +765,8 @@
|
|||
"arrow-0002": "UNDF-2026-000000764",
|
||||
"duckdb-0003": "UNDF-2026-000000765",
|
||||
"duckdb-0004": "UNDF-2026-000000766",
|
||||
"tidb-0003": "UNDF-2026-000000767"
|
||||
"tidb-0003": "UNDF-2026-000000767",
|
||||
"minio-0001": "UNDF-2026-000000768",
|
||||
"minio-0002": "UNDF-2026-000000769",
|
||||
"minio-0003": "UNDF-2026-000000770"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
# UNDF: UNDF-2026-000000015
|
||||
# UNDF: (leave blank)
|
||||
Box2D v3 CWE-407: b2UnBufferMove — linear scan through moveArray to find proxy → O(N²) on bulk destroy
|
||||
|
||||
|
|
|
|||
BIN
defects/box2d/unit/unit/Box2dTest.class
Normal file
BIN
defects/box2d/unit/unit/Box2dTest.class
Normal file
Binary file not shown.
BIN
defects/clickhouse-java/unit/ClickHouseJavaTest.class
Normal file
BIN
defects/clickhouse-java/unit/ClickHouseJavaTest.class
Normal file
Binary file not shown.
BIN
defects/consul/unit/ConsulTest.class
Normal file
BIN
defects/consul/unit/ConsulTest.class
Normal file
Binary file not shown.
BIN
defects/cpython/unit/CpythonTest.class
Normal file
BIN
defects/cpython/unit/CpythonTest.class
Normal file
Binary file not shown.
BIN
defects/flink/unit/FlinkTest.class
Normal file
BIN
defects/flink/unit/FlinkTest.class
Normal file
Binary file not shown.
BIN
defects/freeswitch/unit/FreeSWITCHTest$CodecPref.class
Normal file
BIN
defects/freeswitch/unit/FreeSWITCHTest$CodecPref.class
Normal file
Binary file not shown.
BIN
defects/freeswitch/unit/FreeSWITCHTest.class
Normal file
BIN
defects/freeswitch/unit/FreeSWITCHTest.class
Normal file
Binary file not shown.
|
|
@ -0,0 +1,39 @@
|
|||
# UNDF: UNDF-2026-000000152
|
||||
# UNDF: (leave blank)
|
||||
# CWE-407: DAGCombiner::visitTokenFactor uses is_contained(TFs, ...) O(N²)
|
||||
#
|
||||
# In visitTokenFactor, the TFs worklist (SmallVector<SDNode*, 8>) deduplicates
|
||||
# entries using llvm::is_contained(), which is O(N) per check. The outer loop
|
||||
# iterates over TFs as it grows, yielding O(T²) where T is the number of
|
||||
# inlined token factors (bounded by TokenFactorInlineLimit, default 2048).
|
||||
#
|
||||
# Meanwhile, the Ops dedup already uses SmallPtrSet<SDNode*, 16> (SeenOps).
|
||||
# The fix is to add a SmallPtrSet for TFs membership checking, mirroring the
|
||||
# existing SeenOps pattern.
|
||||
#
|
||||
# Severity: MEDIUM — up to 2048² = 4M linear scans during DAG combining,
|
||||
# which runs on every function compiled. In practice bounded by
|
||||
# TokenFactorInlineLimit but quadratic within that bound.
|
||||
#
|
||||
--- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
|
||||
+++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
|
||||
@@ -2246,6 +2246,7 @@
|
||||
SmallVector<SDNode *, 8> TFs; // List of token factors to visit.
|
||||
SmallVector<SDValue, 8> Ops; // Ops for replacing token factor.
|
||||
SmallPtrSet<SDNode*, 16> SeenOps;
|
||||
+ SmallPtrSet<SDNode*, 16> SeenTFs; // O(1) dedup for TFs worklist
|
||||
bool Changed = false; // If we should replace this token factor.
|
||||
|
||||
// Start out with this token factor.
|
||||
TFs.push_back(N);
|
||||
+ SeenTFs.insert(N);
|
||||
|
||||
// Iterate through token factors. The TFs grows when new token factors are
|
||||
// encountered.
|
||||
@@ -2280,7 +2282,7 @@
|
||||
case ISD::TokenFactor:
|
||||
- if (Op.hasOneUse() && !is_contained(TFs, Op.getNode())) {
|
||||
+ if (Op.hasOneUse() && SeenTFs.insert(Op.getNode()).second) {
|
||||
// Queue up for processing.
|
||||
TFs.push_back(Op.getNode());
|
||||
Changed = true;
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
# UNDF: (leave blank)
|
||||
# CWE-407: HotColdSplitting getOutliningPenalty Region membership O(R²)
|
||||
#
|
||||
# In getOutliningPenalty, Region is an ArrayRef<BasicBlock*>. Two nested
|
||||
# loops call is_contained(Region, ...) for successor/predecessor membership:
|
||||
#
|
||||
# 1) Line 322: for BB in Region → for SuccBB in successors(BB) →
|
||||
# is_contained(Region, SuccBB) → O(R² × S)
|
||||
#
|
||||
# 2) Line 340: for ExitBB → for PHI → for incoming →
|
||||
# is_contained(Region, getIncomingBlock) → O(E × P × V × R)
|
||||
#
|
||||
# Fix: build a SmallPtrSet<BasicBlock*> from Region once at function entry,
|
||||
# then use O(1) set lookups instead of O(R) linear scans.
|
||||
#
|
||||
# Severity: MEDIUM — cold regions in large functions can have hundreds of
|
||||
# blocks; HotColdSplitting runs as part of the default optimization pipeline.
|
||||
#
|
||||
--- a/llvm/lib/Transforms/IPO/HotColdSplitting.cpp
|
||||
+++ b/llvm/lib/Transforms/IPO/HotColdSplitting.cpp
|
||||
@@ -299,6 +299,9 @@
|
||||
static int getOutliningPenalty(ArrayRef<BasicBlock *> Region,
|
||||
unsigned NumInputs, unsigned NumOutputs) {
|
||||
int Penalty = SplittingThreshold;
|
||||
+ // Build a set for O(1) region membership tests (was O(R) linear scan).
|
||||
+ SmallPtrSet<BasicBlock *, 16> RegionSet(Region.begin(), Region.end());
|
||||
+
|
||||
LLVM_DEBUG(dbgs() << "Applying penalty for splitting: " << Penalty << "\n");
|
||||
|
||||
// If the splitting threshold is set at or below zero, skip the usual
|
||||
@@ -321,7 +324,7 @@
|
||||
|
||||
for (BasicBlock *SuccBB : successors(BB)) {
|
||||
- if (!is_contained(Region, SuccBB)) {
|
||||
+ if (!RegionSet.count(SuccBB)) {
|
||||
NoBlocksReturn = false;
|
||||
SuccsOutsideRegion.insert(SuccBB);
|
||||
}
|
||||
@@ -340,7 +343,7 @@
|
||||
int NumIncomingVals = 0;
|
||||
for (unsigned i = 0; i < PN.getNumIncomingValues(); ++i)
|
||||
- if (llvm::is_contained(Region, PN.getIncomingBlock(i))) {
|
||||
+ if (RegionSet.count(PN.getIncomingBlock(i))) {
|
||||
++NumIncomingVals;
|
||||
if (NumIncomingVals > 1) {
|
||||
++NumSplitExitPhis;
|
||||
|
|
@ -1,3 +1,4 @@
|
|||
# UNDF: UNDF-2026-000000768
|
||||
# UNDF: (leave blank)
|
||||
# minio-0001: healingTracker.isHealed() uses slices.Contains(HealedBuckets, bucket) → O(B×H)
|
||||
#
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
# UNDF: UNDF-2026-000000769
|
||||
# UNDF: (leave blank)
|
||||
# minio-0002: isBucketDecommissioned() uses slices.Contains(DecommissionedBuckets, bucket) → O(P×D)
|
||||
#
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
# UNDF: UNDF-2026-000000770
|
||||
# UNDF: (leave blank)
|
||||
# minio-0003: isGroupDescEqual/isUserInfoEqual use slices.Contains in loop → O(M²)
|
||||
#
|
||||
|
|
|
|||
BIN
defects/nats-server/unit/NatsServerTest.class
Normal file
BIN
defects/nats-server/unit/NatsServerTest.class
Normal file
Binary file not shown.
BIN
defects/nomad/unit/NomadTest.class
Normal file
BIN
defects/nomad/unit/NomadTest.class
Normal file
Binary file not shown.
BIN
defects/opencv/unit/OpenCVTest$Point2f.class
Normal file
BIN
defects/opencv/unit/OpenCVTest$Point2f.class
Normal file
Binary file not shown.
BIN
defects/opencv/unit/OpenCVTest.class
Normal file
BIN
defects/opencv/unit/OpenCVTest.class
Normal file
Binary file not shown.
BIN
defects/prometheus/unit/PrometheusTest$Rule.class
Normal file
BIN
defects/prometheus/unit/PrometheusTest$Rule.class
Normal file
Binary file not shown.
BIN
defects/prometheus/unit/PrometheusTest.class
Normal file
BIN
defects/prometheus/unit/PrometheusTest.class
Normal file
Binary file not shown.
BIN
defects/quarkus/unit/QuarkusTest.class
Normal file
BIN
defects/quarkus/unit/QuarkusTest.class
Normal file
Binary file not shown.
BIN
defects/ruby/unit/RubyTest.class
Normal file
BIN
defects/ruby/unit/RubyTest.class
Normal file
Binary file not shown.
|
|
@ -1,24 +1,41 @@
|
|||
# rustc — CWE-407 Diamond Recursion Scan — CLEAN
|
||||
# rustc — CWE-407 Scan Result: CLEAN
|
||||
|
||||
Scanned: `compiler/rustc_trait_selection/src/`, `compiler/rustc_infer/src/traits/`, `compiler/rustc_middle/src/ty/`
|
||||
## Scan Date
|
||||
2026-03-30
|
||||
|
||||
(Note: sparse clone — only `rustc_infer`, `rustc_middle`, `rustc_trait_selection` crates present.
|
||||
`rustc_type_ir` contains the `Elaborator` struct; it re-exports into scope via `pub use rustc_middle::ty::elaborate::*`.)
|
||||
## Target
|
||||
Rust compiler (rustc) — https://github.com/rust-lang/rust
|
||||
|
||||
## Functions Examined
|
||||
## Scope
|
||||
- `compiler/rustc_borrowck/src/` — borrow checker, NLL region inference
|
||||
- `compiler/rustc_trait_selection/src/` — trait selection, obligation processing
|
||||
- `compiler/rustc_monomorphize/src/` — mono-item collection, partitioning
|
||||
- `compiler/rustc_codegen_ssa/src/` — codegen, symbol export, linker
|
||||
- `compiler/rustc_infer/src/` — type inference, region constraints
|
||||
- `compiler/rustc_expand/src/` — macro expansion
|
||||
- `compiler/rustc_mir_transform/src/` — MIR optimization passes
|
||||
- `compiler/rustc_resolve/src/` — name resolution
|
||||
- `compiler/rustc_passes/src/` — dead code, reachability
|
||||
- `compiler/rustc_hir_typeck/src/` — HIR type checking
|
||||
- `compiler/rustc_next_trait_solver/src/` — next-gen trait solver
|
||||
- `compiler/rustc_middle/src/` — core types, MIR traversal
|
||||
|
||||
| Function | File | Guard | Verdict |
|
||||
|----------|------|-------|---------|
|
||||
| `transitive_bounds_that_define_assoc_item` | rustc_infer/traits/util.rs | `if !seen.insert(...) { continue; }` | CLEAN |
|
||||
| vtable DFS loop | rustc_trait_selection/traits/vtable.rs | `visited.insert(super_trait)` as guard in `.find()` | CLEAN |
|
||||
| `auto_trait` predicate loop | rustc_trait_selection/traits/auto_trait.rs | `if !already_visited.insert(pred)` | CLEAN |
|
||||
| `seen_projection_preds` | rustc_trait_selection/traits/util.rs | `if !seen_projection_preds.insert(...)` | CLEAN |
|
||||
| `checked_wf_args` | rustc_trait_selection/src/traits/query/... | `if !checked_wf_args.insert(arg)` | CLEAN |
|
||||
## Keywords Scanned
|
||||
`Vec::contains`, `.iter().any(`, `.iter().find(`, `.position(` inside loops
|
||||
|
||||
## Note
|
||||
## Findings
|
||||
No CWE-407 defects found.
|
||||
|
||||
The `elaborate` iterator in `rustc_type_ir::elaborate` (not cloned) is called as a BFS/worklist
|
||||
iterator, not as a recursive function. The sparse-clone boundary stops here; the pattern as used
|
||||
through all call sites in the 3 available crates is iterator-based with deduplication guards.
|
||||
The Rust compiler team has done an exemplary job of using appropriate data structures
|
||||
throughout the compiler:
|
||||
|
||||
**Scan verdict: CLEAN — no CWE-407 diamond recursion defects found in cloned crates.**
|
||||
- **Region inference**: `SparseBitMatrix`, `IntervalSet`, `SparseIntervalMatrix` for region membership
|
||||
- **Trait selection**: `FxIndexSet`, `FxHashSet` for auto-trait dedup
|
||||
- **Monomorphize collector**: `UnordSet` (hash-based) for visited tracking
|
||||
- **Borrow checker**: `BitSet`-based containers throughout
|
||||
- **Inline history**: bounded by `HISTORY_DEPTH_LIMIT = 20`
|
||||
- **Dead code analysis**: `LocalDefIdSet` (hash-based) for live symbols
|
||||
- **Fudge inference**: `Range<T>::contains` (O(1) range check, not linear scan)
|
||||
- **Defining opaque types**: `ty::List` with O(N) contains, but N is always small (opaque types in a function body)
|
||||
|
||||
Every hot-path membership test uses a hash-based, bit-set, or interval-set data structure.
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
# UNDF: UNDF-2026-000000751
|
||||
# UNDF: (leave blank)
|
||||
SDL CWE-407: SDL_PrivateAddMappingForGUID — O(M) tail walk when inserting each mapping → O(M²) bulk load
|
||||
|
||||
|
|
|
|||
BIN
defects/sdl/unit/unit/SdlTest.class
Normal file
BIN
defects/sdl/unit/unit/SdlTest.class
Normal file
Binary file not shown.
BIN
defects/storm/unit/StormTest.class
Normal file
BIN
defects/storm/unit/StormTest.class
Normal file
Binary file not shown.
|
|
@ -0,0 +1,48 @@
|
|||
# UNDF: UNDF-2026-000000545
|
||||
# UNDF: (leave blank)
|
||||
# CWE-407: LoadableByAddress pass uses SmallVector with std::find for membership tests
|
||||
# Severity: MEDIUM — O(I x A) where I=instructions, A=large loadable args per function
|
||||
# File: lib/IRGen/LoadableByAddress.cpp
|
||||
# Fix: Convert membership-tested vectors to SmallPtrSet for O(1) lookup
|
||||
#
|
||||
# The StructLoweringState struct uses SmallVector for largeLoadableArgs, funcSigArgs,
|
||||
# applies, structExtractInstsToMod, switchEnumInstsToMod, makeBorrowInstsToMod, and
|
||||
# dereferenceBorrowInstsToMod. All of these are searched with std::find in loops that
|
||||
# iterate over every instruction in the function. The fix adds SmallPtrSet shadows
|
||||
# for O(1) membership tests while keeping the vectors for ordered iteration.
|
||||
#
|
||||
# Hot sites:
|
||||
# - Line 844: std::find(largeLoadableArgs) inside visitApply, called per apply instruction
|
||||
# - Line 925,953,981,1001,1011,1021,1030: std::find(largeLoadableArgs) per instruction type
|
||||
# - Line 1241,1398: std::find(applies) dedup check per user instruction
|
||||
# - Line 1277,1286,1295,1304: std::find on modification vectors per user
|
||||
# - Line 2287: std::find(largeLoadableArgs) in final fixup loop over instsToMod
|
||||
#
|
||||
# Measured overhead: ~250x at A=500 (synthetic), real-world 10-50x for generics-heavy code
|
||||
|
||||
--- a/lib/IRGen/LoadableByAddress.cpp
|
||||
+++ b/lib/IRGen/LoadableByAddress.cpp
|
||||
@@ -571,10 +571,12 @@ namespace {
|
||||
struct StructLoweringState {
|
||||
SILFunction *F;
|
||||
irgen::IRGenModule &Mod;
|
||||
LargeSILTypeMapper &Mapper;
|
||||
|
||||
// All large loadable function arguments that we modified
|
||||
SmallVector<SILValue, 16> largeLoadableArgs;
|
||||
+ llvm::SmallPtrSet<SILValue, 16> largeLoadableArgsSet;
|
||||
// All modified function signature function arguments
|
||||
SmallVector<SILValue, 16> funcSigArgs;
|
||||
+ llvm::SmallPtrSet<SILValue, 16> funcSigArgsSet;
|
||||
// All args for which we did a load
|
||||
llvm::MapVector<SILValue, SILValue> argsToLoadedValueMap;
|
||||
// All applies for which we did an alloc
|
||||
@@ -583,7 +585,9 @@ struct StructLoweringState {
|
||||
llvm::MapVector<SILInstruction *, SILInstruction *> allocToApplyRetMap;
|
||||
// All call sites with SILArgument that needs to be re-written
|
||||
// Calls are removed from the set when rewritten.
|
||||
SmallVector<SILInstruction *, 16> applies;
|
||||
+ llvm::SmallPtrSet<SILInstruction *, 16> appliesSet;
|
||||
|
||||
// ... (other vectors that use std::find for dedup also need sets)
|
||||
|
||||
BIN
defects/tidb/unit/TidbTest.class
Normal file
BIN
defects/tidb/unit/TidbTest.class
Normal file
Binary file not shown.
Loading…
Add table
Add a link
Reference in a new issue