Files
node/test/parallel/test-permission-fs-supported.js
Marco 1a885caa6e fs: add mkstemp()
Add fs.mkstemp(), fs.mkstempSync() and fsPromises.mkstemp(), which
create and open a unique temporary file in one operation. They expose
uv_fs_mkstemp(), the file counterpart of the function behind
fs.mkdtemp().

The callback and sync versions return the path and a file descriptor,
the promise version returns the path and a FileHandle.

libuv clears the path of the request when mkstemp() fails, so the
template is saved in the request and used for the path of the error.

The functions are also supported on mounted virtual file systems.

Refs: https://github.com/nodejs/node/pull/33549
Refs: https://github.com/nodejs/node/issues/33890
Refs: https://github.com/nodejs/node/issues/5332
Signed-off-by: marcopiraccini <marco.piraccini@gmail.com>
PR-URL: https://github.com/nodejs/node/pull/66484
Reviewed-By: Paolo Insogna <paolo@cowtech.it>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
Reviewed-By: Gürgün Dayıoğlu <hey@gurgun.day>
2026-10-19 02:34:09 +00:00

126 lines
3.9 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
'use strict';
require('../common');
const assert = require('assert');
// Most of the times, the function called for async and Sync
// methods are the same on node_file.cc
function syncAndAsyncAPI(funcName) {
return [funcName, funcName + 'Sync'];
}
// This tests guarantee whenever a new API under fs module is exposed
// it must contain a test to the permission model.
// Otherwise, a vulnerability might be exposed. If you are adding a new
// fs method, please, make sure to include a test for it on test-permission-fs-*
// and include to the supportedApis list.
//
//
// This list is synced with
// fixtures/permission/fs-read and
// fixtures/permission/fs-write
const supportedApis = [
...syncAndAsyncAPI('appendFile'),
...syncAndAsyncAPI('access'),
...syncAndAsyncAPI('chown'),
...syncAndAsyncAPI('chmod'),
...syncAndAsyncAPI('copyFile'),
...syncAndAsyncAPI('cp'),
'createReadStream',
'createWriteStream',
...syncAndAsyncAPI('exists'),
...syncAndAsyncAPI('lchown'),
...syncAndAsyncAPI('lchmod'),
...syncAndAsyncAPI('link'),
...syncAndAsyncAPI('lutimes'),
...syncAndAsyncAPI('mkdir'),
...syncAndAsyncAPI('mkdtemp'),
...syncAndAsyncAPI('open'),
...syncAndAsyncAPI('openAsBlob'),
...syncAndAsyncAPI('mkdtemp'),
'mkdtempDisposableSync',
...syncAndAsyncAPI('mkstemp'),
...syncAndAsyncAPI('readdir'),
...syncAndAsyncAPI('readFile'),
...syncAndAsyncAPI('readlink'),
...syncAndAsyncAPI('rename'),
...syncAndAsyncAPI('rm'),
...syncAndAsyncAPI('rmdir'),
...syncAndAsyncAPI('stat'),
...syncAndAsyncAPI('statfs'),
...syncAndAsyncAPI('statfs'),
...syncAndAsyncAPI('symlink'),
...syncAndAsyncAPI('truncate'),
...syncAndAsyncAPI('unlink'),
...syncAndAsyncAPI('utimes'),
'watch',
'watchFile',
...syncAndAsyncAPI('writeFile'),
...syncAndAsyncAPI('opendir'),
];
// Non functions
const ignoreList = [
'constants',
'promises',
'X_OK',
'W_OK',
'R_OK',
'F_OK',
'Dir',
// the Utf8Stream is implemented in terms of functions
// on the fs module that have permission checks, so we don't
// need to check it here.
'Utf8Stream',
'FileReadStream',
'FileWriteStream',
'_toUnixTimestamp',
'Stats',
'ReadStream',
'WriteStream',
'Dirent',
// fs.watch is already blocked
'unwatchFile',
...syncAndAsyncAPI('lstat'),
...syncAndAsyncAPI('realpath'),
// File descriptor–based metadata operations
//
// The kernel does not allow opening a file descriptor for an inode
// with write access if the inode itself is read-only. However, it still
// permits modifying the inode’s metadata (e.g., permission bits, ownership,
// timestamps) because you own the file. These changes can be made either
// by referring to the file by name (e.g., chmod) or through any existing
// file descriptor that identifies the same inode (e.g., fchmod).
//
// If the kernel required write access to change metadata, it would be
// impossible to modify the permissions of a file once it was made read-only.
// For that reason, syscalls such as fchmod, fchown, and futimes bypass
// the file descriptor’s access mode. Even a read-only ('r') descriptor
// can still update metadata. To prevent unintended modifications,
// these APIs are therefore blocked by default when permission model is
// enabled.
...syncAndAsyncAPI('close'),
...syncAndAsyncAPI('fchown'),
...syncAndAsyncAPI('fchmod'),
...syncAndAsyncAPI('fdatasync'),
...syncAndAsyncAPI('fstat'),
...syncAndAsyncAPI('fsync'),
...syncAndAsyncAPI('ftruncate'),
...syncAndAsyncAPI('futimes'),
...syncAndAsyncAPI('read'),
...syncAndAsyncAPI('readv'),
...syncAndAsyncAPI('write'),
...syncAndAsyncAPI('writev'),
...syncAndAsyncAPI('glob'),
];
{
const fsList = Object.keys(require('fs'));
for (const k of fsList) {
if (!supportedApis.includes(k) && !ignoreList.includes(k)) {
assert.fail(`fs.${k} was exposed but is neither on the supported list ` +
'of the permission model nor on the ignore list.');
}
}
}