From ee363534285292be50dcbffdeb9b85b6d4e2d6bb Mon Sep 17 00:00:00 2001 From: Philipp Dunkel Date: Fri, 4 Sep 2026 18:48:33 +0200 Subject: [PATCH] vfs: load native addons from a mounted file system A native addon inside a virtual file system could not be require()d: dlopen() and LoadLibrary() open a shared object by path, and a VFS path has no inode for them to open. Read the addon's bytes from the VFS and load them from a private, self-cleaning image instead, using the smallest on-disk footprint each platform allows: on Linux an anonymous memfd loaded through /proc/self/fd, so the bytes never reach the file system; on other POSIX platforms a file in a 0700 mkdtemp() directory, unlinked right after loading, with the mapping keeping it alive; on Windows a temp file opened FILE_FLAG_DELETE_ON_CLOSE whose handle is held until exit. This is internal. process.dlopen() keeps its documented (module, filename[, flags]) signature and ignores anything further; the bytes are passed to a dlopenBinary() reachable only through the process_methods binding, which the VFS hook calls for VFS paths. Addons on the real file system are untouched and load directly. Signed-off-by: Philipp Dunkel PR-URL: https://github.com/nodejs/node/pull/65680 Reviewed-By: Matteo Collina Reviewed-By: Paolo Insogna Reviewed-By: James M Snell --- doc/api/cli.md | 23 ++ doc/api/vfs.md | 6 + doc/node.1 | 13 + lib/internal/vfs/setup.js | 22 ++ src/node_binding.cc | 358 +++++++++++++++++- src/node_binding.h | 1 + src/node_options.cc | 6 + src/node_options.h | 1 + src/node_process_methods.cc | 2 + test/parallel/test-dlopen-binary.js | 51 +++ .../parallel/test-permission-dlopen-binary.js | 113 ++++++ test/parallel/test-vfs-addon.js | 37 ++ 12 files changed, 627 insertions(+), 6 deletions(-) create mode 100644 test/parallel/test-dlopen-binary.js create mode 100644 test/parallel/test-permission-dlopen-binary.js create mode 100644 test/parallel/test-vfs-addon.js diff --git a/doc/api/cli.md b/doc/api/cli.md index 220af9fcf22..32c91c26974 100644 --- a/doc/api/cli.md +++ b/doc/api/cli.md @@ -268,6 +268,26 @@ process.permission.has('fs.read', 'custom-require.js'); // true process.permission.has('fs.read', 'custom-require-2.js'); // true ``` +### `--allow-fs-vfs` + + + +> Stability: 1.1 - Active development + +When using the [Permission Model][], a [virtual file system][] cannot be +mounted by default: [`vfs.mount()`][] throws `ERR_INVALID_STATE` unless the +user explicitly passes the `--allow-fs-vfs` flag when starting Node.js. + +A mounted VFS serves paths that the file system permissions do not describe, +so mounting one is gated on its own flag rather than on `--allow-fs-read` or +`--allow-fs-write`. + +```console +$ node --experimental-vfs --permission --allow-fs-vfs app.js +``` + ### `--allow-fs-write`