Skip to content

JerryScript: configurable module namespace re-export causes type confusion and crash #5294

@shi-bohao

Description

@shi-bohao

Summary

JerryScript creates some module namespace object properties with the wrong property attributes. In ecma_module_create_namespace_object, namespace re-export entries are created with ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE, which makes the exported namespace property configurable.

ECMA-262 requires module namespace exotic object properties to be non-configurable. Because the property is configurable, JavaScript code can redefine or delete it. After that, ordinary namespace-object operations can observe an invalid internal property state and crash the engine.

Security impact

  • Suggested severity: Medium to High, depending on whether untrusted modules can be loaded by the embedding application
  • Suggested CWE: CWE-843 (possible type confusion / incompatible interpretation of an internal value)
  • Attack surface: pure JavaScript module input, through the shipped jerry -m CLI or embedders that load ES modules
  • Observed impact: release build segmentation fault; ASan reports an invalid read while copying/refcounting a corrupted ECMAScript value

Root cause

At jerry-core/ecma/base/ecma-module.c:887, namespace re-export data properties are created as configurable:

property_value_p = ecma_create_named_data_property (module_p->namespace_object_p,
                                                    ecma_get_string_from_value (buffer_p[0]),
                                                    ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE,
                                                    NULL);
property_value_p->value = buffer_p[1];

This bug is specific to namespace re-export entries such as export * as ns from ...; ordinary exported bindings use a different reference-property representation. Namespace re-export data properties should use non-configurable namespace property attributes, for example enumerable + writable + non-configurable.

JerryScript revision

Observed at JerryScript commit:

b7069350c2e52e7dc721dfb75f067147bd79b39b

Tested on: 2026-06-20.

Build platform
Ubuntu 24.04.4 LTS (Linux 6.6.87.2-microsoft-standard-WSL2 x86_64)
Build steps

Release build:

python3 tools/build.py --clean

Debug build:

python3 tools/build.py --clean --debug

ASan build used for the backtrace:

python3 tools/build.py --clean \
  --builddir=build-asan \
  --compile-flag=-fsanitize=address \
  --linker-flag=-fsanitize=address \
  --strip=OFF
Build log

Not a build problem. Build completed successfully.

Test case

Create the following files in one directory.

main.mjs:

import * as ns from './dep.mjs';

try {
  Reflect.ownKeys(ns);
  Object.defineProperty(ns, 'ns', {
    get: function() {
      return 1;
    },
    configurable: true
  });
  Reflect.ownKeys(ns);
  Object.keys(ns);
  delete ns.ns;
} catch (e) {
}

dep.mjs:

export * as ns from './mid.mjs';
export * from './mid.mjs';

mid.mjs:

export let foo = class {};
export let x = class {};
export * as ns from './leaf.mjs';
export * from './leaf.mjs';

leaf.mjs:

export let bar = {};
export let x = {};
Execution platform

Same as the build platform.

Execution steps
build/bin/jerry -m main.mjs

For ASan:

ASAN_OPTIONS=detect_leaks=0 build-asan/bin/jerry -m main.mjs
Output

Release build:

Segmentation fault
exit=139

Debug build:

Aborted
exit=134

ASan build:

AddressSanitizer:DEADLYSIGNAL
ERROR: AddressSanitizer: SEGV on unknown address
The signal is caused by a READ memory access.
Backtrace

Representative ASan stack:

#0 ecma_copy_value
#1 ecma_op_object_get_own_property
#2 ecma_op_object_get_own_property_descriptor
#3 ecma_op_object_get_enumerable_property_names
#4 ecma_builtin_object_dispatch_routine
#5 ecma_op_function_call_native_built_in
#6 ecma_op_function_call
#7 vm_execute
#8 vm_run
#9 ecma_module_evaluate
#10 main
Expected behavior

Module namespace object properties must be non-configurable. Object.defineProperty(ns, "ns", ...) must throw a TypeError, the existing namespace export property must remain unchanged, and the engine must not crash.

Suggested fix

Use non-configurable module namespace property attributes when creating namespace re-export data properties:

- ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE,
+ ECMA_PROPERTY_ENUMERABLE_WRITABLE,

This matches the expected module namespace property attributes: writable true, enumerable true, configurable false.

Regression test suggestion

Add a module regression test that verifies Object.defineProperty on a namespace re-export property throws a TypeError, and that the namespace object can still be enumerated normally afterwards.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions