openfoam-0003: DSMCCloud::initialise calls findIndex(typeIdList_, moleculeName) inside triple-nested forAll(cells) * forAll(tets) * forAll(molecules) loop. Fix: pre-build HashTable<label, word> before cell loop for O(1) lookups. 3-10x speedup depending on type count. 5/5 PASS. root-cern-0003: TTree::InitializeBranchLists calls std::find on fSeqBranches (std::vector<TBranch*>) inside two O(B) loops, yielding O(B^2) total. Fix: mirror fSeqBranches in std::unordered_set<TBranch*> for O(1) lookup. ~500x speedup at B=500, ~1000x at B=1000 (CMS NanoAOD scale). 6/6 PASS. MOAD-0002: OpenFOAM objectRegistry god-object structural, ROOT gROOT intertangle structural (gROOTMutex inconsistently applied). Both documented. MOAD-0003: ROOT TTHREAD_TLS method-scoped only, CLEAN. OpenFOAM no thread-local, CLEAN. MOAD-0004: OpenFOAM CLEAN. ROOT TWebFile auth logging pre-existing root-cern-0002. MOAD-0005: Both CLEAN.
2.9 KiB
ROOT (CERN): 5-MOAD scan results (2026-04-03)
MOAD-0001 (CWE-407) -- NEW: root-cern-0003
TTree::InitializeBranchLists() calls std::find on fSeqBranches
(std::vector<TBranch*>) twice per branch in two separate loops:
- Count-leaf loop: for each of B branches, O(S) scan to check if its count branch is already in fSeqBranches.
- Partition loop: for each of B branches, O(S) scan to check if it is a seq branch.
Total: O(B * S) for each loop = O(B^2) in worst case (all count leaves).
At B=1000 (CMS NanoAOD scale): ~2,000,000 pointer comparisons vs ~2,000
with std::unordered_set<TBranch*>. Speedup: ~1000x.
Triggered on first GetEntry() with ROOT Implicit MultiThreading (IMT) enabled.
File: tree/tree/src/TTree.cxx, function TTree::InitializeBranchLists.
Pre-existing defects:
- root-cern-0001: TTreeCache::FillBuffer potentialVetoes std::find O(B*N^2) MEDIUM
- root-cern-0002: TWebFile GetFromWeb10 Authorization header logged at gDebug>0 HIGH
Other candidates examined:
- RDFInterfaceUtils.cxx line 202: std::find in for loop but usedCols is bounded by the formula column count (typically <20), not a scaling defect.
- RGeomData.cxx: std::find on pchlds/chlds, per-node operation only, O(children) bounded.
- TTree.cxx line 5879/5894: same defect as root-cern-0003, same function.
MOAD-0002 (Intertangle) -- STRUCTURAL, document only
ROOT's gROOT (TROOT) is a global god-object: all TTrees, TChains, TFiles, TDirectories, TH1s register themselves into gROOT->GetListOfSpecials(), GetListOfCleanups(), GetListOfDataSets() etc. The mutex coverage is inconsistent: GetListOfCleanups is guarded by gROOTMutex but GetListOfSpecials and GetListOfDataSets are accessed unguarded (TChain constructor lines 82/89). This is a long-standing architectural coupling that is not addressable with a local patch. ROOT 7 (RNTuple/RDataFrame) moves away from gROOT but TTrees remain.
MOAD-0003 (Leaked Context) -- CLEAN
ROOT's TTHREAD_TLS usage is limited to TMVA internals (MethodMLP, BinaryTree, TNeuron, etc.) holding method-scoped state (iteration counters, random state) rather than request-scoped identity. No web-service or per-request identity propagation via thread-locals found.
MOAD-0004 (CWE-312) -- EXISTING root-cern-0002
TWebFile::GetFromWeb10 at gDebug>0 logs full HTTP request including Authorization: Basic base64(user:password). TS3WebFile similarly logs AWS access keys. Documented in root-cern-0002.
MOAD-0005 (Thundering Herd) -- CLEAN
TFormula::gClingFunctions static unordered_map is consistently guarded by R__LOCKGUARD(gROOTMutex) before every read/write. TGeoParallelWorld static candidates vector is guarded by a dedicated std::mutex in InitSafetyVoxel. RWebDisplayHandle::FindCreator static map lacks a mutex but is called only from GUI display code which ROOT users treat as single-threaded. No unsynchronized cache-get+null+set pattern found in hot paths.