HSEC-2026-0012: Out-of-bounds read in Eq and Ord on numbers with extreme exponents
Out-of-bounds read in Eq and Ord on numbers with extreme exponents
scientific-0.3.9.0 reimplemented Eq and Ord without normalising their arguments. The new implementation short-circuits on integerLog10' c + e computed in Int, which overflows when the base-10 exponent is close to maxBound :: Int. The overflowed comparison then falls through to magnitude (e1 - e2), where the exponent difference overflows to a negative Int as well. magnitude indexed its cached power-of-ten array without a bounds check, so the negative index performed an out-of-bounds read and the process died with SIGSEGV.
With scientific-0.3.9.0 (GHC 9.10.3, x8664-linux), as reported in basvandijk/scientific#120:
haskell import Data.Scientific
main :: IO () main = print (scientific 10 maxBound == scientific 1 minBound)
$ ./repro; echo "exit=$?" exit=139
The issue was discovered when Stackage nightly test suites (genvalidity-hspec-aeson, genvalidity-sydtest-aeson) started segfaulting after upgrading to scientific-0.3.9.0: their property tests round-trip aeson Values, which produces Scientifics with extreme exponents.
Versions before 0.3.9.0 did not crash, but Eq/Ord returned invalid results there instead (the normalisation-based implementation overflows the exponent, reporting scientific 10 maxBound == scientific 1 minBound as True). The same unchecked read was also reachable through (+) and (-) on older versions, guarded only by the documented warning about the potential 10^e blowup — reading outside the cache is not.
Resolution
scientific-0.3.10.0 computes the logarithms using Integer, fixing both the crash and the invalid comparison results, and bounds-checks magnitude, so a negative exponent now raises an error instead of reading out of bounds. All entry points (Eq, Ord, (+), (-)) are covered; upgrade to scientific-0.3.10.0 or later.
Note that printing values with exponents close to maxBound :: Int remains unreliable due to the inherent Int exponent overflow in normalize; this limitation is documented upstream and postponed to the next major release.
Credits
Reported by Tom Sydney Kerckhove (@NorfairKing); fixed by Oleg Grenrus (@phadej).
Affected Software
Event History
Frequently Asked Questions
Which deployments are exposed to this crash?
Applications using scientific-0.3.9.0 are exposed when they compare Scientific values whose base-10 exponents are close to the Int bounds. The reported failure occurred on GHC 9.10.3 for x86_64 Linux.
What must an attacker or input source be able to do to trigger it?
They must cause Eq or Ord to compare Scientific numbers with extreme exponents. The supplied reproducer compares scientific 10 maxBound with scientific 1 minBound and terminates with SIGSEGV.
How can I determine whether my application is affected?
Check whether the resolved dependency is scientific-0.3.9.0. Applications that deserialize or generate Scientific values with unbounded or extreme exponents, including through aeson Value round-trip tests, should specifically test comparisons involving those values.