Skip to content

Commit fd3ea29

Browse files
jbergstroemcjihrig
authored andcommitted
test: fix test-fs-access when uid is 0
Superusers can open files with W_OK permission even though their mode is set to 0444. This commit makes the test attempt to change its uid to nobody on non-Windows platforms. Patch originally from nodejs/node-v0.x-archive@28d0cbbd. Fixes: #1031 PR-URL: #1037 Reviewed-By: Colin Ihrig <[email protected]>
1 parent 5abfa93 commit fd3ea29

File tree

1 file changed

+46
-6
lines changed

1 file changed

+46
-6
lines changed

test/parallel/test-fs-access.js

+46-6
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ var fs = require('fs');
44
var path = require('path');
55
var doesNotExist = __filename + '__this_should_not_exist';
66
var readOnlyFile = path.join(common.tmpDir, 'read_only_file');
7+
var readWriteFile = path.join(common.tmpDir, 'read_write_file');
78

89
var removeFile = function(file) {
910
try {
@@ -13,13 +14,47 @@ var removeFile = function(file) {
1314
}
1415
};
1516

16-
var createReadOnlyFile = function(file) {
17+
var createFileWithPerms = function(file, mode) {
1718
removeFile(file);
1819
fs.writeFileSync(file, '');
19-
fs.chmodSync(file, 0444);
20+
fs.chmodSync(file, mode);
2021
};
2122

22-
createReadOnlyFile(readOnlyFile);
23+
createFileWithPerms(readOnlyFile, 0444);
24+
createFileWithPerms(readWriteFile, 0666);
25+
26+
/*
27+
* On non-Windows supported platforms, fs.access(readOnlyFile, W_OK, ...)
28+
* always succeeds if node runs as the super user, which is sometimes the
29+
* case for tests running on our continuous testing platform agents.
30+
*
31+
* In this case, this test tries to change its process user id to a
32+
* non-superuser user so that the test that checks for write access to a
33+
* read-only file can be more meaningful.
34+
*
35+
* The change of user id is done after creating the fixtures files for the same
36+
* reason: the test may be run as the superuser within a directory in which
37+
* only the superuser can create files, and thus it may need superuser
38+
* priviledges to create them.
39+
*
40+
* There's not really any point in resetting the process' user id to 0 after
41+
* changing it to 'nobody', since in the case that the test runs without
42+
* superuser priviledge, it is not possible to change its process user id to
43+
* superuser.
44+
*
45+
* It can prevent the test from removing files created before the change of user
46+
* id, but that's fine. In this case, it is the responsability of the
47+
* continuous integration platform to take care of that.
48+
*/
49+
var hasWriteAccessForReadonlyFile = false;
50+
if (process.platform !== 'win32' && process.getuid() === 0) {
51+
hasWriteAccessForReadonlyFile = true;
52+
try {
53+
process.setuid('nobody');
54+
hasWriteAccessForReadonlyFile = false;
55+
} catch (err) {
56+
}
57+
}
2358

2459
assert(typeof fs.F_OK === 'number');
2560
assert(typeof fs.R_OK === 'number');
@@ -45,8 +80,12 @@ fs.access(readOnlyFile, fs.F_OK | fs.R_OK, function(err) {
4580
});
4681

4782
fs.access(readOnlyFile, fs.W_OK, function(err) {
48-
assert.notEqual(err, null, 'error should exist');
49-
assert.strictEqual(err.path, readOnlyFile);
83+
if (hasWriteAccessForReadonlyFile) {
84+
assert.equal(err, null, 'error should not exist');
85+
} else {
86+
assert.notEqual(err, null, 'error should exist');
87+
assert.strictEqual(err.path, readOnlyFile);
88+
}
5089
});
5190

5291
assert.throws(function() {
@@ -68,7 +107,7 @@ assert.doesNotThrow(function() {
68107
assert.doesNotThrow(function() {
69108
var mode = fs.F_OK | fs.R_OK | fs.W_OK;
70109

71-
fs.accessSync(__filename, mode);
110+
fs.accessSync(readWriteFile, mode);
72111
});
73112

74113
assert.throws(function() {
@@ -79,4 +118,5 @@ assert.throws(function() {
79118

80119
process.on('exit', function() {
81120
removeFile(readOnlyFile);
121+
removeFile(readWriteFile);
82122
});

0 commit comments

Comments
 (0)