Firefox · SpiderMonkey
CVE-2025-9187
Memory Corruption in SpiderMonkey
Overview
High
Severity
—
CVSS
No
Exploited ITW
Fixed
Fix Status
Changed Functions
| Function | Change | Notes |
|---|---|---|
JSONPrinterjs/src/vm/StringType.h |
modified | |
PropertyNamejs/src/vm/StringType.h |
modified | |
StringBuilderjs/src/vm/StringType.h |
modified | |
JSOffThreadAtomjs/src/vm/StringType.h |
modified | |
ParserAtomsTablejs/src/vm/StringType.h |
modified |
Files Changed
js/src/gc/Cell.hjs/src/vm/StringType.h
Patch
diff --git a/js/src/gc/Cell.h b/js/src/gc/Cell.h
index 7a7d455ae37..b4ed6086f5d 100644
--- a/js/src/gc/Cell.h
+++ b/js/src/gc/Cell.h
@@ -627,8 +627,18 @@ class alignas(gc::CellAlignBytes) CellWithLengthAndFlags : public Cell {
return uint32_t(header_.get() >> 32);
#endif
}
+ uint32_t headerLengthFieldAtomic() const {
+#if JS_BITS_PER_WORD == 32
+ return length_;
+#else
+ return uint32_t(header_.getAtomic() >> 32);
+#endif
+ }
uint32_t headerFlagsField() const { return uint32_t(header_.get()); }
+ uint32_t headerFlagsFieldAtomic() const {
+ return uint32_t(header_.getAtomic());
+ }
void setHeaderFlagBit(uint32_t flag) {
header_.set(header_.get() | uintptr_t(flag));
diff --git a/js/src/vm/StringType.h b/js/src/vm/StringType.h
index ed4142a10ef..9eee35a4474 100644
--- a/js/src/vm/StringType.h
+++ b/js/src/vm/StringType.h
@@ -48,6 +48,7 @@ class JS_PUBLIC_API GenericPrinter;
class JSONPrinter;
class PropertyName;
class StringBuilder;
+class JSOffThreadAtom;
namespace frontend {
class ParserAtomsTable;
@@ -736,6 +737,12 @@ class JSString : public js::gc::CellWithLengthAndFlags {
return *(JSAtom*)this;
}
+ MOZ_ALWAYS_INLINE
+ js::JSOffThreadAtom& asOffThreadAtom() const {
+ MOZ_ASSERT(headerFlagsFieldAtomic() & ATOM_BIT);
+ return *(js::JSOffThreadAtom*)this;
+ }
+
MOZ_ALWAYS_INLINE
void setNonDeduplicatable() {
MOZ_ASSERT(isLinear());
@@ -1799,6 +1806,17 @@ class StringSegmentRange {
}
};
+// This class should be used in code that manipulates strings off-thread (for
+// example, Ion compilation). The key difference is that flags are loaded
+// atomically, preventing data races if flags (especially the pinned atom bit)
+// are mutated on the main thread. We use private inheritance to avoid
+// accidentally exposing anything non-thread-safe.
+class JSOffThreadAtom : private JSAtom {
+ public:
+ size_t length() const { return headerLengthFieldAtomic(); }
+ size_t flags() const { return headerFlagsFieldAtomic(); }
+};
+
} // namespace js
inline js::HashNumber JSAtom::hash() const {
Loading diff…
References
On This Page