Skip to content

Commit d38ea17

Browse files
committed
lib,permission: disable fchmod/fchown when pm enabled
PR-URL: nodejs-private/node-private#584 Refs: https://hackerone.com/reports/2472071 CVE-ID: CVE-2024-36137
1 parent d162dca commit d38ea17

File tree

2 files changed

+43
-0
lines changed

2 files changed

+43
-0
lines changed

lib/fs.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1888,6 +1888,11 @@ function fchmod(fd, mode, callback) {
18881888
mode = parseFileMode(mode, 'mode');
18891889
callback = makeCallback(callback);
18901890

1891+
if (permission.isEnabled()) {
1892+
callback(new ERR_ACCESS_DENIED('fchmod API is disabled when Permission Model is enabled.'));
1893+
return;
1894+
}
1895+
18911896
const req = new FSReqCallback();
18921897
req.oncomplete = callback;
18931898
binding.fchmod(fd, mode, req);
@@ -1900,6 +1905,9 @@ function fchmod(fd, mode, callback) {
19001905
* @returns {void}
19011906
*/
19021907
function fchmodSync(fd, mode) {
1908+
if (permission.isEnabled()) {
1909+
throw new ERR_ACCESS_DENIED('fchmod API is disabled when Permission Model is enabled.');
1910+
}
19031911
binding.fchmod(
19041912
fd,
19051913
parseFileMode(mode, 'mode'),
@@ -2032,6 +2040,10 @@ function fchown(fd, uid, gid, callback) {
20322040
validateInteger(uid, 'uid', -1, kMaxUserId);
20332041
validateInteger(gid, 'gid', -1, kMaxUserId);
20342042
callback = makeCallback(callback);
2043+
if (permission.isEnabled()) {
2044+
callback(new ERR_ACCESS_DENIED('fchown API is disabled when Permission Model is enabled.'));
2045+
return;
2046+
}
20352047

20362048
const req = new FSReqCallback();
20372049
req.oncomplete = callback;
@@ -2048,6 +2060,9 @@ function fchown(fd, uid, gid, callback) {
20482060
function fchownSync(fd, uid, gid) {
20492061
validateInteger(uid, 'uid', -1, kMaxUserId);
20502062
validateInteger(gid, 'gid', -1, kMaxUserId);
2063+
if (permission.isEnabled()) {
2064+
throw new ERR_ACCESS_DENIED('fchown API is disabled when Permission Model is enabled.');
2065+
}
20512066

20522067
binding.fchown(fd, uid, gid);
20532068
}

test/fixtures/permission/fs-write.js

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -464,4 +464,32 @@ const absoluteProtectedFolder = path.resolve(relativeProtectedFolder);
464464
permission: 'FileSystemWrite',
465465
resource: path.toNamespacedPath(blockedFile),
466466
});
467+
}
468+
469+
// fs.fchown with read-only fd
470+
{
471+
assert.throws(() => {
472+
// blocked file is allowed to read
473+
const fd = fs.openSync(blockedFile, 'r');
474+
fs.fchmod(fd, 777, common.expectsError({
475+
code: 'ERR_ACCESS_DENIED',
476+
}));
477+
fs.fchmodSync(fd, 777);
478+
}, {
479+
code: 'ERR_ACCESS_DENIED',
480+
});
481+
}
482+
483+
// fs.fchmod with read-only fd
484+
{
485+
assert.throws(() => {
486+
// blocked file is allowed to read
487+
const fd = fs.openSync(blockedFile, 'r');
488+
fs.fchown(fd, 999, 999, common.expectsError({
489+
code: 'ERR_ACCESS_DENIED',
490+
}));
491+
fs.fchownSync(fd, 999, 999);
492+
}, {
493+
code: 'ERR_ACCESS_DENIED',
494+
});
467495
}

0 commit comments

Comments
 (0)