Skip to content

node-api: store external type tags by value

Overview

A change introduced in Node 20.12 and Node 21.6 changes the semantics of tagging External values, and introduces a possible memory bug.

This pull request is responsible for the change: https://github.com/nodejs/node/pull/51149

The code in this commit stores the type tag pointer and not the 128-bit value inside. This breaks some pre-existing code that were making temporary tags. It also means that unloading the module will cause existing External objects to have a tag pointer that points... "nowhere" (use-after-free).

This violates what is stated in the N-API documentation:

A type tag is a 128-bit integer unique to the addon. Node-API provides the napi_type_tag structure for storing a type tag. [...] This creates a type-checking capability of a higher fidelity than napi_instanceof() can provide, because such type- tagging survives prototype manipulation and addon unloading/reloading.

For objects, nothing has changed since type tags are still stored in a private property (in a BigInt). So the pointer does not get stale.

This potential bug was reported here: #52387 (closed)

Patch series

The first patch fixes the issue, the second patch changes existing type tagging tests to make sure this issue does not reoccur in the future.

Merge request reports

Loading