permission: block FileHandle fsync and fdatasync

Signed-off-by: RafaelGSS <rafael.nunu@hotmail.com>
PR-URL: https://github.com/nodejs/node/pull/65431
Reviewed-By: James M Snell <jasnell@gmail.com>
This commit is contained in:
Rafael Gonzaga authored and GitHub committed 2026-08-27 14:10:47 +00:00
1 parent 4f7e2147cf
commit d6e67a5e30
3 files changed
+47

No files matched your search

+8
View File
@@ -258,6 +258,14 @@ does not exist, the wildcard will not be added, and access will be limited to
yet, make sure to explicitly include the wildcard:
`/my-path/folder-do-not-exist/*`.
Some `node:fs` operations act on an already-open file descriptor rather than a
path, so they cannot be tied to a `--allow-fs-read` or `--allow-fs-write` grant.
When the permission model is enabled these operations are disabled and throw
`ERR_ACCESS_DENIED`, regardless of how the descriptor was obtained. This applies
both to the top-level `node:fs` functions and to the equivalent
`FileHandle` methods, and currently includes `fsync`/`fdatasync`,
`fchmod`, and `fchown` (and their synchronous variants).
#### Configuration file support
In addition to passing permission flags on the command line, they can also be
+6
View File
@@ -1598,6 +1598,9 @@ async function rmdir(path, options) {
}
async function fdatasync(handle) {
if (permission.isEnabled()) {
throw new ERR_ACCESS_DENIED('fdatasync API is disabled when Permission Model is enabled.');
}
return await PromisePrototypeThen(
binding.fdatasync(handle.fd, kUsePromises),
undefined,
@@ -1606,6 +1609,9 @@ async function fdatasync(handle) {
}
async function fsync(handle) {
if (permission.isEnabled()) {
throw new ERR_ACCESS_DENIED('fsync API is disabled when Permission Model is enabled.');
}
return await PromisePrototypeThen(
binding.fsync(handle.fd, kUsePromises),
undefined,
@@ -0,0 +1,33 @@
// Flags: --permission --allow-fs-read=*
'use strict';
const common = require('../common');
const { isMainThread } = require('worker_threads');
if (!isMainThread) {
common.skip('This test only works on a main thread');
}
const assert = require('assert');
const { open } = require('fs/promises');
const fixtures = require('../common/fixtures');
const regularFile = fixtures.path('permission', 'deny', 'regular-file.md');
// FileHandle sync operations must be blocked when the permission model is
// enabled, consistent with fs.fsync() / fs.fsyncSync() and fdatasync variants.
(async () => {
const fh = await open(regularFile, 'r');
try {
await assert.rejects(
fh.sync(),
common.expectsError({ code: 'ERR_ACCESS_DENIED' }),
);
await assert.rejects(
fh.datasync(),
common.expectsError({ code: 'ERR_ACCESS_DENIED' }),
);
} finally {
await fh.close();
}
})().then(common.mustCall());