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, x86_64-linux), as
reported in basvandijk/scientific#120:
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).
Info
- Published
- November 03, 2026
- Modified
- November 03, 2026
- CAPECs
- < none >
- CWEs
- 125
- 190
- Keywords
- memory-safety, oob-read, segfault
- Aliases
- < none >
- Related
- HSEC-2026-0011
- References
- [REPORT] https://github.com/basvandijk/scientific/issues/120
- [REPORT] https://github.com/NorfairKing/validity/issues/121
- [FIX] https://github.com/basvandijk/scientific/pull/121
- [DISCUSSION] https://www.reddit.com/r/haskell/comments/1xbj59g/dont_use_scientific_for_calculations_it_can/
Affected
@hackage/scientific
- CVSS
- CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:H
- Versions
>=0.3.9.0 && <0.3.10.0- Declarations
- < none >
- Affected APIs
- < none >