Firefox · SpiderMonkey
CVE-2026-16410
Logic Error in SpiderMonkey
Overview
Low
Severity
—
CVSS
No
Exploited ITW
Fixed
Fix Status
Changed Functions
| Function | Change | Notes |
|---|---|---|
withjs/src/jit-test/tests/ion/bug2053680.js |
modified | |
forjs/src/jit-test/tests/ion/bug2053680.js |
modified |
Files Changed
js/src/jit-test/tests/ion/bug2053680.jsjs/src/jit/RangeAnalysis.cpp
Patch
diff --git a/js/src/jit-test/tests/ion/bug2053680.js b/js/src/jit-test/tests/ion/bug2053680.js
new file mode 100644
index 00000000000..02969289f87
--- /dev/null
+++ b/js/src/jit-test/tests/ion/bug2053680.js
@@ -0,0 +1,17 @@
+// |jit-test| --disable-main-thread-denormals; --fast-warmup; --ion-check-range-analysis; skip-if: !getBuildConfiguration("can-disable-main-thread-denormals")
+function f(x) {
+ x = Math.fround(x);
+ if (x >= Math.fround(-1e-40)) {
+ return x ? x : 0;
+ }
+ return 7;
+}
+function test() {
+ with ({}) {} // Don't Ion-compile this function.
+ var res = 0;
+ for (var i = 0; i < 1000; i++) {
+ res += f(Math.fround(-1e-40));
+ }
+ assertEq(res, 0);
+}
+test();
diff --git a/js/src/jit/RangeAnalysis.cpp b/js/src/jit/RangeAnalysis.cpp
index 5d538b81875..6ff34ea874e 100644
--- a/js/src/jit/RangeAnalysis.cpp
+++ b/js/src/jit/RangeAnalysis.cpp
@@ -718,14 +718,19 @@ void Range::setDouble(double l, double h) {
canHaveFractionalPart_ = ExcludesFractionalParts;
canBeNegativeZero_ = ExcludesNegativeZero;
- // If denormals are disabled, any value with exponent 0 will be immediately
- // flushed to 0. This gives 2**53 bit patterns that compare equal to zero.
+ // If denormals are disabled, any denormal value will be immediately flushed
+ // to 0, so any bit pattern in the denormal range compares equal to zero.
//
- // Check whether the range [l .. h] can cross any of the 2^53 zeros. We have
- // to be conservative as the main thread might not interpret doubles the same
- // way as the compiler thread.
- const double doubleMin = mozilla::BitwiseCast<double>(
- mozilla::SpecificFloatingPointBits<double, 0, 1, 0>::value);
+ // Check whether the range [l .. h] can cross any of these zeros. We have to
+ // be conservative as the main thread might not interpret floating point
+ // values the same way as the compiler thread.
+ //
+ // This Range may describe a Float32 value, whose denormal range begins at
+ // the smallest normal binary32 (2**-126) rather than the smallest normal
+ // binary64 (2**-1022). Use the (wider) binary32 threshold so we stay
+ // conservative for both float32 and double values.
+ const double doubleMin = double(mozilla::BitwiseCast<float>(
+ mozilla::SpecificFloatingPointBits<float, 0, 1, 0>::value));
bool includesNegative = std::isnan(l) || l < doubleMin;
bool includesPositive = std::isnan(h) || h > -doubleMin;
bool crossesZero = includesNegative && includesPositive;
Loading diff…
Regression Test / PoC
shipped with the fix
diff --git a/js/src/jit-test/tests/ion/bug2053680.js b/js/src/jit-test/tests/ion/bug2053680.js
new file mode 100644
index 00000000000..02969289f87
--- /dev/null
+++ b/js/src/jit-test/tests/ion/bug2053680.js
@@ -0,0 +1,17 @@
+// |jit-test| --disable-main-thread-denormals; --fast-warmup; --ion-check-range-analysis; skip-if: !getBuildConfiguration("can-disable-main-thread-denormals")
+function f(x) {
+ x = Math.fround(x);
+ if (x >= Math.fround(-1e-40)) {
+ return x ? x : 0;
+ }
+ return 7;
+}
+function test() {
+ with ({}) {} // Don't Ion-compile this function.
+ var res = 0;
+ for (var i = 0; i < 1000; i++) {
+ res += f(Math.fround(-1e-40));
+ }
+ assertEq(res, 0);
+}
+test();
Loading diff…
References
On This Page