hsec-2023-0007
Vulnerability from osv_haskell
Published
2025-11-14 14:45
Modified
2025-11-14 14:45
Summary
readFloat: memory exhaustion with large exponent
Details

readFloat: memory exhaustion with large exponent

Numeric.readFloat takes time and memory linear in the size of the number denoted by the input string. In particular, processing a number expressed in scientific notation with a very large exponent could cause a denial of service. The slowdown is observable on a modern machine running GHC 9.4.4:

ghci> import qualified Numeric
ghci> Numeric.readFloat "1e1000000"    -- near instantaneous
[(Infinity,"")]
ghci> Numeric.readFloat "1e10000000"   -- perceptible pause
[(Infinity,"")]
ghci> Numeric.readFloat "1e100000000"  -- ~ 3 seconds
[(Infinity,"")]
ghci> Numeric.readFloat "1e1000000000" -- ~ 35 seconds
[(Infinity,"")]

In base

Numeric.readFloat is defined for all RealFrac a => a:

readFloat :: RealFrac a => ReadS a

The RealFrac type class does not express any bounds on the size of values representable in the types for which instances exist, so bounds checking is not possible (in this generic function). readFloat uses to Text.Read.Lex.numberToRational which, among other things, calculates 10 ^ exponent, which seems to take linear time and memory.

Mitigation: use read. The Read instances for Float and Double perform bounds checks on the exponent, via Text.Read.Lex.numberToRangedRational.

In toml-reader

The issue was detected in toml-reader version 0.1.0.0, and mitigated in version 0.2.0.0 by immediately returning Infinity when the exponent is large enough that there's no reason to process it.


{
  "affected": [
    {
      "database_specific": {
        "human_link": "https://github.com/haskell/security-advisories/tree/main/advisories/published/2023/HSEC-2023-0007.md",
        "osv": "https://raw.githubusercontent.com/haskell/security-advisories/refs/heads/generated/osv-export/2023/HSEC-2023-0007.json"
      },
      "package": {
        "ecosystem": "Hackage",
        "name": "base"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "3.0.3.1"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ],
      "severity": [
        {
          "score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H",
          "type": "CVSS_V3"
        }
      ]
    },
    {
      "database_specific": {
        "human_link": "https://github.com/haskell/security-advisories/tree/main/advisories/published/2023/HSEC-2023-0007.md",
        "osv": "https://raw.githubusercontent.com/haskell/security-advisories/refs/heads/generated/osv-export/2023/HSEC-2023-0007.json"
      },
      "package": {
        "ecosystem": "Hackage",
        "name": "toml-reader"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0.1.0.0"
            },
            {
              "fixed": "0.2.0.0"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ],
      "severity": [
        {
          "score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H",
          "type": "CVSS_V3"
        }
      ]
    }
  ],
  "database_specific": {
    "home": "https://github.com/haskell/security-advisories",
    "osvs": "https://raw.githubusercontent.com/haskell/security-advisories/refs/heads/generated/osv-export",
    "repository": "https://github.com/haskell/security-advisories"
  },
  "details": "# `readFloat`: memory exhaustion with large exponent\n\n`Numeric.readFloat` takes time and memory linear in the size of the\nnumber _denoted_ by the input string.  In particular, processing a\nnumber expressed in scientific notation with a very large exponent\ncould cause a denial of service.  The slowdown is observable on a\nmodern machine running GHC 9.4.4:\n\n```\nghci\u003e import qualified Numeric\nghci\u003e Numeric.readFloat \"1e1000000\"    -- near instantaneous\n[(Infinity,\"\")]\nghci\u003e Numeric.readFloat \"1e10000000\"   -- perceptible pause\n[(Infinity,\"\")]\nghci\u003e Numeric.readFloat \"1e100000000\"  -- ~ 3 seconds\n[(Infinity,\"\")]\nghci\u003e Numeric.readFloat \"1e1000000000\" -- ~ 35 seconds\n[(Infinity,\"\")]\n```\n\n## In *base*\n\n`Numeric.readFloat` is defined for all `RealFrac a =\u003e a`:\n\n```haskell\nreadFloat :: RealFrac a =\u003e ReadS a\n```\n\nThe `RealFrac` type class does not express any bounds on the size of\nvalues representable in the types for which instances exist, so\nbounds checking is not possible (in this *generic* function).\n`readFloat` uses to `Text.Read.Lex.numberToRational` which, among\nother things, calculates `10 ^ exponent`, which seems to take linear\ntime and memory.\n\n**Mitigation:** use `read`.  The `Read` instances for `Float` and\n`Double` perform bounds checks on the exponent, via\n`Text.Read.Lex.numberToRangedRational`.\n\n\n## In *toml-reader*\n\nThe issue was detected in *toml-reader* version 0.1.0.0, and\nmitigated in version 0.2.0.0 by immediately returning `Infinity`\nwhen the exponent is large enough that there\u0027s no reason to process\nit.\n",
  "id": "HSEC-2023-0007",
  "modified": "2025-11-14T14:45:34Z",
  "published": "2025-11-14T14:45:34Z",
  "references": [
    {
      "type": "REPORT",
      "url": "https://gitlab.haskell.org/ghc/ghc/-/issues/23538"
    },
    {
      "type": "REPORT",
      "url": "https://github.com/brandonchinn178/toml-reader/issues/8"
    },
    {
      "type": "FIX",
      "url": "https://github.com/brandonchinn178/toml-reader/pull/9"
    }
  ],
  "schema_version": "1.5.0",
  "summary": "readFloat: memory exhaustion with large exponent"
}


Log in or create an account to share your comment.




Tags
Taxonomy of the tags.


Loading…

Loading…

Loading…

Sightings

Author Source Type Date

Nomenclature

  • Seen: The vulnerability was mentioned, discussed, or observed by the user.
  • Confirmed: The vulnerability has been validated from an analyst's perspective.
  • Published Proof of Concept: A public proof of concept is available for this vulnerability.
  • Exploited: The vulnerability was observed as exploited by the user who reported the sighting.
  • Patched: The vulnerability was observed as successfully patched by the user who reported the sighting.
  • Not exploited: The vulnerability was not observed as exploited by the user who reported the sighting.
  • Not confirmed: The user expressed doubt about the validity of the vulnerability.
  • Not patched: The vulnerability was not observed as successfully patched by the user who reported the sighting.


Loading…

Detection rules are retrieved from Rulezet.

Loading…

Loading…