Every CVESearch/Get API key

HSEC-2026-0012

Out-of-bounds read in Eq and Ord on numbers with extreme exponents

No scoreFix available

HSEC-2026-0012 is a vulnerability with no CVSS score yet in scientific, published November 3, 2026. No source lists public exploit code. Fixed in scientific 0.3.10.0.

What does this mean?
Severity
UnratedNo CVSS score yet
Exploit chance
UnscoredNo EPSS score yet
Exploitation
None knownNot on CISA’s or ENISA’s lists
Fixed in
0.3.10.0scientific

Description

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).

Affected packages

Affected packages
PackageAffectedFixed
scientific
Hackage
0.3.9.0 up to 0.3.10.0
0.3.10.0

What each source reports

OSVNo score

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, 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).

Record
HSEC-2026-0012
Updated
2026-11-03

History

History
RecordedChangedSources
first indexedOSV

Dates are when Every CVE recorded each change. Upstream dates may differ.

References

MoveEnter Open