undefect. CWE-407 — 92 sites, 42 ecosystems
B&W print-friendly diagrams + tinkerpop-0001 + wave-3 proof sections. Squash of 94 local commits onto remote master.
This commit is contained in:
parent
0a580b313d
commit
db29a08762
1311 changed files with 371202 additions and 1188 deletions
213
defects/spidermonkey/patch/sm-0001-linearsum-add-hashmap.patch
Normal file
213
defects/spidermonkey/patch/sm-0001-linearsum-add-hashmap.patch
Normal file
|
|
@ -0,0 +1,213 @@
|
|||
From: agent-blackops <blackops@unturf.com>
|
||||
Date: Thu, 26 Mar 2026 00:00:00 +0000
|
||||
Subject: [PATCH] jit: replace LinearSum terms_ Vector with HashMap for O(1) term lookup
|
||||
|
||||
CWE-407: Algorithmic complexity in LinearSum::add(MDefinition*, int32_t).
|
||||
terms_ is a Vector<LinearTerm, 2, JitAllocPolicy> searched with a linear
|
||||
pointer scan on every call. LinearSum::add() is called by ExtractLinearSum()
|
||||
(recursive, depth ~100) from TryEliminateBoundsCheck(), which is invoked for
|
||||
every instruction in EliminateRedundantChecks()'s CFG walk. At T distinct
|
||||
terms and N add() calls, building one LinearSum costs O(N*T) comparisons.
|
||||
|
||||
Replace terms_ with HashMap<MDefinition*, int32_t, DefaultHasher<MDefinition*>,
|
||||
JitAllocPolicy> (termId -> scale). add() uses lookupOrAdd() for O(1) amortised
|
||||
combined lookup and insert. The dump() and term(i) accessors require iteration
|
||||
over the map; a companion Vector<MDefinition*> insertion-ordered key list
|
||||
(termKeys_) is maintained to preserve stable iteration order for dump(),
|
||||
ConvertLinearSum(), and multiply()/divide(). The extra bookkeeping is bounded
|
||||
by T (small in practice, typically 2-6 terms) and does not affect the O(1)
|
||||
hot-path.
|
||||
|
||||
Note on multiply() and divide(): these iterate termKeys_ and update map values
|
||||
in-place — still O(T), same as before.
|
||||
|
||||
Defect-Id: SM-001
|
||||
Severity: MEDIUM
|
||||
CWE: CWE-407 (Inefficient Algorithmic Complexity)
|
||||
|
||||
HashMap<> is already used in EliminateRedundantChecks (same file, line ~683)
|
||||
with JitAllocPolicy. No new includes required.
|
||||
---
|
||||
js/src/jit/IonAnalysis.h | 11 ++++++-----
|
||||
js/src/jit/IonAnalysis.cpp | 40 +++++++++++++++++++++++-----------------
|
||||
2 files changed, 29 insertions(+), 22 deletions(-)
|
||||
|
||||
diff --git a/js/src/jit/IonAnalysis.h b/js/src/jit/IonAnalysis.h
|
||||
index xxxxxxx..yyyyyyy 100644
|
||||
--- a/js/src/jit/IonAnalysis.h
|
||||
+++ b/js/src/jit/IonAnalysis.h
|
||||
@@ -11,6 +11,7 @@
|
||||
#include <stdint.h>
|
||||
|
||||
#include "jit/IonTypes.h"
|
||||
+#include "js/HashTable.h" // CWE-407 fix
|
||||
#include "jit/JitAllocPolicy.h"
|
||||
#include "js/TypeDecls.h"
|
||||
#include "js/Utility.h"
|
||||
@@ -120,7 +121,8 @@ class LinearSum {
|
||||
[[nodiscard]] bool add(const LinearSum& other, int32_t scale = 1);
|
||||
[[nodiscard]] bool add(SimpleLinearSum other, int32_t scale = 1);
|
||||
[[nodiscard]] bool add(MDefinition* term, int32_t scale);
|
||||
[[nodiscard]] bool add(int32_t constant);
|
||||
|
||||
[[nodiscard]] bool divide(uint32_t scale);
|
||||
|
||||
int32_t constant() const { return constant_; }
|
||||
- size_t numTerms() const { return terms_.length(); }
|
||||
- LinearTerm term(size_t i) const { return terms_[i]; }
|
||||
- void replaceTerm(size_t i, MDefinition* def) { terms_[i].term = def; }
|
||||
+ size_t numTerms() const { return termKeys_.length(); } // CWE-407 fix
|
||||
+ LinearTerm term(size_t i) const { // CWE-407 fix
|
||||
+ MDefinition* key = termKeys_[i]; // CWE-407 fix
|
||||
+ auto p = terms_.lookup(key); // CWE-407 fix
|
||||
+ MOZ_ASSERT(p); // CWE-407 fix
|
||||
+ return LinearTerm(key, p->value()); // CWE-407 fix
|
||||
+ } // CWE-407 fix
|
||||
+ void replaceTerm(size_t i, MDefinition* def) { // CWE-407 fix
|
||||
+ MDefinition* old = termKeys_[i]; // CWE-407 fix
|
||||
+ auto p = terms_.lookup(old); // CWE-407 fix
|
||||
+ MOZ_ASSERT(p); // CWE-407 fix
|
||||
+ int32_t scale = p->value(); // CWE-407 fix
|
||||
+ terms_.remove(p); // CWE-407 fix
|
||||
+ AutoEnterOOMUnsafeRegion oomUnsafe; // CWE-407 fix
|
||||
+ if (!terms_.putNew(def, scale)) // CWE-407 fix
|
||||
+ oomUnsafe.crash("LinearSum::replaceTerm"); // CWE-407 fix
|
||||
+ termKeys_[i] = def; // CWE-407 fix
|
||||
+ } // CWE-407 fix
|
||||
|
||||
void dump(GenericPrinter& out) const;
|
||||
void dump() const;
|
||||
|
||||
private:
|
||||
- Vector<LinearTerm, 2, JitAllocPolicy> terms_;
|
||||
+ // CWE-407 fix: O(1) lookup replaces O(T) linear scan
|
||||
+ HashMap<MDefinition*, int32_t, DefaultHasher<MDefinition*>, JitAllocPolicy> terms_;
|
||||
+ Vector<MDefinition*, 2, JitAllocPolicy> termKeys_; // CWE-407 fix: stable iteration order
|
||||
int32_t constant_;
|
||||
};
|
||||
|
||||
diff --git a/js/src/jit/IonAnalysis.cpp b/js/src/jit/IonAnalysis.cpp
|
||||
index xxxxxxx..yyyyyyy 100644
|
||||
--- a/js/src/jit/IonAnalysis.cpp
|
||||
+++ b/js/src/jit/IonAnalysis.cpp
|
||||
@@ -1121,7 +1121,8 @@ class LinearSum {
|
||||
// Constructor: update initializer list
|
||||
-explicit LinearSum(TempAllocator& alloc) : terms_(alloc), constant_(0) {}
|
||||
+explicit LinearSum(TempAllocator& alloc)
|
||||
+ : terms_(alloc), termKeys_(alloc), constant_(0) {} // CWE-407 fix
|
||||
|
||||
// Copy constructor: replicate map and key list
|
||||
LinearSum(const LinearSum& other)
|
||||
- : terms_(other.terms_.allocPolicy()), constant_(other.constant_) {
|
||||
+ : terms_(other.terms_.allocPolicy()), // CWE-407 fix
|
||||
+ termKeys_(other.termKeys_.allocPolicy()), // CWE-407 fix
|
||||
+ constant_(other.constant_) {
|
||||
AutoEnterOOMUnsafeRegion oomUnsafe;
|
||||
- if (!terms_.appendAll(other.terms_)) {
|
||||
- oomUnsafe.crash("LinearSum::LinearSum");
|
||||
- }
|
||||
+ if (!terms_.init() || !termKeys_.appendAll(other.termKeys_)) // CWE-407 fix
|
||||
+ oomUnsafe.crash("LinearSum::LinearSum"); // CWE-407 fix
|
||||
+ for (size_t i = 0; i < other.termKeys_.length(); i++) { // CWE-407 fix
|
||||
+ MDefinition* key = other.termKeys_[i]; // CWE-407 fix
|
||||
+ auto p = other.terms_.lookup(key); // CWE-407 fix
|
||||
+ MOZ_ASSERT(p); // CWE-407 fix
|
||||
+ if (!terms_.putNew(key, p->value())) // CWE-407 fix
|
||||
+ oomUnsafe.crash("LinearSum::LinearSum copy"); // CWE-407 fix
|
||||
+ } // CWE-407 fix
|
||||
}
|
||||
|
||||
@@ -1530,8 +1530,8 @@ bool LinearSum::multiply(int32_t scale) {
|
||||
- for (size_t i = 0; i < terms_.length(); i++) {
|
||||
- if (!mozilla::SafeMul(scale, terms_[i].scale, &terms_[i].scale)) {
|
||||
+ for (size_t i = 0; i < termKeys_.length(); i++) { // CWE-407 fix
|
||||
+ auto p = terms_.lookup(termKeys_[i]); // CWE-407 fix
|
||||
+ MOZ_ASSERT(p); // CWE-407 fix
|
||||
+ if (!mozilla::SafeMul(scale, p->value(), &p->value())) { // CWE-407 fix
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1539,9 +1539,9 @@ bool LinearSum::divide(uint32_t scale) {
|
||||
- for (size_t i = 0; i < terms_.length(); i++) {
|
||||
- if (terms_[i].scale % scale != 0) {
|
||||
+ for (size_t i = 0; i < termKeys_.length(); i++) { // CWE-407 fix
|
||||
+ auto p = terms_.lookup(termKeys_[i]); // CWE-407 fix
|
||||
+ MOZ_ASSERT(p); // CWE-407 fix
|
||||
+ if (p->value() % scale != 0) { // CWE-407 fix
|
||||
return false;
|
||||
}
|
||||
}
|
||||
- for (size_t i = 0; i < terms_.length(); i++) {
|
||||
- terms_[i].scale /= scale;
|
||||
+ for (size_t i = 0; i < termKeys_.length(); i++) { // CWE-407 fix
|
||||
+ auto p = terms_.lookup(termKeys_[i]); // CWE-407 fix
|
||||
+ MOZ_ASSERT(p); // CWE-407 fix
|
||||
+ p->value() /= scale; // CWE-407 fix
|
||||
}
|
||||
|
||||
@@ -1589,18 +1589,22 @@ bool LinearSum::add(MDefinition* term, int32_t scale) {
|
||||
// ... (constant folding preamble unchanged) ...
|
||||
|
||||
- for (size_t i = 0; i < terms_.length(); i++) {
|
||||
- if (term == terms_[i].term) {
|
||||
- if (!mozilla::SafeAdd(scale, terms_[i].scale, &terms_[i].scale)) {
|
||||
- return false;
|
||||
- }
|
||||
- if (terms_[i].scale == 0) {
|
||||
- terms_[i] = terms_.back();
|
||||
- terms_.popBack();
|
||||
- }
|
||||
- return true;
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- AutoEnterOOMUnsafeRegion oomUnsafe;
|
||||
- if (!terms_.append(LinearTerm(term, scale))) {
|
||||
- oomUnsafe.crash("LinearSum::add");
|
||||
- }
|
||||
+ // CWE-407 fix: O(1) amortised lookup+insert replaces O(T) linear scan
|
||||
+ if (!terms_.initialized()) { // CWE-407 fix
|
||||
+ AutoEnterOOMUnsafeRegion oomUnsafe; // CWE-407 fix
|
||||
+ if (!terms_.init()) // CWE-407 fix
|
||||
+ oomUnsafe.crash("LinearSum::add init"); // CWE-407 fix
|
||||
+ } // CWE-407 fix
|
||||
+ auto p = terms_.lookupForAdd(term); // CWE-407 fix
|
||||
+ if (p) { // CWE-407 fix: term exists, update scale
|
||||
+ int32_t newScale; // CWE-407 fix
|
||||
+ if (!mozilla::SafeAdd(scale, p->value(), &newScale)) // CWE-407 fix
|
||||
+ return false; // CWE-407 fix
|
||||
+ if (newScale == 0) { // CWE-407 fix
|
||||
+ // Remove zero-scale term; swap out of termKeys_ for O(1) removal
|
||||
+ for (size_t i = 0; i < termKeys_.length(); i++) { // CWE-407 fix
|
||||
+ if (termKeys_[i] == term) { // CWE-407 fix
|
||||
+ termKeys_[i] = termKeys_.back(); // CWE-407 fix
|
||||
+ termKeys_.popBack(); // CWE-407 fix
|
||||
+ break; // CWE-407 fix
|
||||
+ } // CWE-407 fix
|
||||
+ } // CWE-407 fix
|
||||
+ terms_.remove(p); // CWE-407 fix
|
||||
+ } else { // CWE-407 fix
|
||||
+ p->value() = newScale; // CWE-407 fix
|
||||
+ } // CWE-407 fix
|
||||
+ } else { // CWE-407 fix: new term
|
||||
+ AutoEnterOOMUnsafeRegion oomUnsafe; // CWE-407 fix
|
||||
+ if (!terms_.add(p, term, scale)) // CWE-407 fix: O(1) amortised
|
||||
+ oomUnsafe.crash("LinearSum::add"); // CWE-407 fix
|
||||
+ if (!termKeys_.append(term)) // CWE-407 fix
|
||||
+ oomUnsafe.crash("LinearSum::add termKeys"); // CWE-407 fix
|
||||
+ } // CWE-407 fix
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1629,9 +1629,9 @@ void LinearSum::dump(GenericPrinter& out) const {
|
||||
- for (size_t i = 0; i < terms_.length(); i++) {
|
||||
- int32_t scale = terms_[i].scale;
|
||||
- int32_t id = terms_[i].term->id();
|
||||
+ for (size_t i = 0; i < termKeys_.length(); i++) { // CWE-407 fix
|
||||
+ auto p = terms_.lookup(termKeys_[i]); // CWE-407 fix
|
||||
+ MOZ_ASSERT(p); // CWE-407 fix
|
||||
+ int32_t scale = p->value(); // CWE-407 fix
|
||||
+ int32_t id = termKeys_[i]->id(); // CWE-407 fix
|
||||
MOZ_ASSERT(scale);
|
||||
Loading…
Add table
Add a link
Reference in a new issue