Skip to content

[Bug]ecma_make_number_value casts out-of-range double to integer -> UBSan float-cast-overflow (SIGILL) (CWE-681) #5303

Open

Description

@1820893135-pixel

Summary

ecma_make_number_value encodes an ecma_number (double) into an ecma_value by first executing ecma_integer_value_t integer_value = (ecma_integer_value_t) ecma_number;. When the double exceeds the representable integer range (e.g., 1e308, or an oversized snapshot number literal), this cast is C undefined behavior; under UBSan (-fsanitize=undefined, trap) it executes __builtin_trap() and raises SIGILL. The function is reached via the snapshot-deserialization number-literal path (ecma_snapshot_get_literal's IS_NUMBER branch).

  • Affected: JerryScript 3.0.0 (jerry-core/ecma/base/ecma-helpers-value.c:572 in ecma_make_number_value)
  • Severity: Medium
  • CWE: CWE-681 (Incorrect Conversion between Numeric Types)

POC

# 0) rebuild POC (SNAP-prefixed malformed snapshot with oversized number literal)
printf '534e41504a5252594600000000000000f800000001000000180000001c0001000030010031000000010d15150700000087000000070100008701000007020000870200000703000087030000070400008704000007050000870500004f0600004f0700004f080000f01f000000000000f0010000100000004f090000470147024703470447054706470747084709470a470b470c510151025103510451055106510751085109510a510b510c34df013529df022c0ddf032c0edf042c0fdf053529df062c10df073500a211df0834a211df09350090129c13df0a2c14df0b9a01029903990499059906990799089909990a990bdf0c560000470a000001006100010062000100630001006400010065000100660001006700010068000100690001006a0001006b00030073756d006e861bf0f9210940000000b08ef00bc20000e0ddb7d5eb41ffffffffffff3f430000' | xxd -r -p > poc.bin

# 1) build (ASan+UBSan with trap, snapshot exec enabled) -- same cmake as issue-1
# 2) reproduce
./jerry_fuzzer poc.bin

Trigger result

ERROR: UBSan: runtime error: value 1e+308 is outside the range of representable values of type 'int' ... (SIGILL via __builtin_trap)
  • Replay exit code: 132 (SIGILL)
  • Deterministic: yes.
Image

Impact

In production builds with UBSan/trap enabled, loading a snapshot containing an oversized number literal deterministically SIGILL-crashes the engine (DoS). In a regular (non-UBSan) build, x86-64 hardware converts the overflow to a fixed value (0x8000000000000000 / 0x80000000) — usually no crash but wrong values, which can be used to bypass numeric checks or cause logic errors. Overall impact: DoS + numeric-semantics defect.

Suggested fix

Before the integer cast, clamp or reject ecma_number values outside the representable integer range (ecma-helpers-value.c:572), e.g., check JERRY_IS_NUMBER bounds or use a saturating conversion when the double is not exactly representable.

Activity

  1. changed the title [-]ecma_make_number_value casts out-of-range double to integer -> UBSan float-cast-overflow (SIGILL) (CWE-681)[/-] [+][Bug]ecma_make_number_value casts out-of-range double to integer -> UBSan float-cast-overflow (SIGILL) (CWE-681)[/+] on Sep 11, 2026
  2. 1820893135-pixel commented on Sep 23, 2026

    @1820893135-pixel
    Author

    Opened #5309 with a fix. Note that the cast appears at three sites in the same
    file, and a value such as 1.5e300 walks from one to the next, so fixing only
    ecma_make_number_value() (line 572) just moves the trap to
    ecma_update_float_number() (1021) and then ecma_value_assign_number() (1073).
    All three now test the range before casting.

    Re-verified on master via the snapshot path from the report:

    ecma-helpers-value.c:572:40: runtime error: -1.5e+10 is outside the range of representable values of type 'int'
    

    The PR extends tests/unit-core/test-api-value-type.c.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions