Skip to content

Commit c50954d

Browse files
committed
fix: fix EACCES error on access by root user
1 parent faaa676 commit c50954d

File tree

3 files changed

+57
-16
lines changed

3 files changed

+57
-16
lines changed

lib/binding.js

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1325,19 +1325,14 @@ Binding.prototype.access = function (filepath, mode, callback, ctx) {
13251325
throw new FSError('ENOENT', filepath);
13261326
}
13271327
if (mode && process.getuid && process.getgid) {
1328-
const itemMode = item.getMode();
1329-
if (item.getUid() === process.getuid()) {
1330-
if ((itemMode & (mode * 64)) !== mode * 64) {
1331-
throw new FSError('EACCES', filepath);
1332-
}
1333-
} else if (item.getGid() === process.getgid()) {
1334-
if ((itemMode & (mode * 8)) !== mode * 8) {
1335-
throw new FSError('EACCES', filepath);
1336-
}
1337-
} else {
1338-
if ((itemMode & mode) !== mode) {
1339-
throw new FSError('EACCES', filepath);
1340-
}
1328+
if (mode & constants.R_OK && !item.canRead()) {
1329+
throw new FSError('EACCES', filepath);
1330+
}
1331+
if (mode & constants.W_OK && !item.canWrite()) {
1332+
throw new FSError('EACCES', filepath);
1333+
}
1334+
if (mode & constants.X_OK && !item.canExecute()) {
1335+
throw new FSError('EACCES', filepath);
13411336
}
13421337
}
13431338
});

test/lib/binding.spec.js

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1625,6 +1625,14 @@ describe('Binding', function () {
16251625
});
16261626

16271627
describe('#access()', function () {
1628+
const originalGetuid = process.getuid;
1629+
const originalGetgid = process.getgid;
1630+
1631+
beforeEach(function () {
1632+
process.getuid = originalGetuid;
1633+
process.getgid = originalGetgid;
1634+
});
1635+
16281636
it('works if file exists', function () {
16291637
const binding = new Binding(system);
16301638
const pathname = path.join('mock-dir', 'one-link.txt');
@@ -1639,7 +1647,7 @@ describe('Binding', function () {
16391647
}, /ENOENT/);
16401648
});
16411649

1642-
if (process.getuid && process.getgid) {
1650+
if (originalGetuid && originalGetgid) {
16431651
it('fails in case of insufficient user permissions', function () {
16441652
const binding = new Binding(system);
16451653
const item = system.getItem(path.join('mock-dir', 'one.txt'));
@@ -1669,6 +1677,16 @@ describe('Binding', function () {
16691677
binding.access(path.join('mock-dir', 'one.txt'), 5);
16701678
}, /EACCES/);
16711679
});
1680+
1681+
it('sould not throw if process runs as root', function () {
1682+
const binding = new Binding(system);
1683+
const item = system.getItem(path.join('mock-dir', 'one.txt'));
1684+
item.setUid(42);
1685+
item.setGid(42);
1686+
item.setMode(parseInt('0000', 8));
1687+
process.getuid = () => 0;
1688+
binding.access(path.join('mock-dir', 'one.txt'), 5);
1689+
});
16721690
}
16731691

16741692
it('fails for bogus paths', function () {

test/lib/item.spec.js

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -139,11 +139,15 @@ describe('Item', function () {
139139
});
140140

141141
if (process.getgid && process.getuid) {
142-
const uid = process.getuid();
143-
const gid = process.getgid();
142+
const originalGetuid = process.getuid;
143+
const originalGetgid = process.getgid;
144+
const uid = originalGetuid();
145+
const gid = originalGetgid();
144146

145147
let item;
146148
beforeEach(function () {
149+
process.getuid = originalGetuid;
150+
process.getgid = originalGetgid;
147151
item = new Item();
148152
});
149153

@@ -220,6 +224,14 @@ describe('Item', function () {
220224
item.setMode(parseInt('0777', 8));
221225
assert.isTrue(item.canRead());
222226
});
227+
228+
it('always returns true if process runs as root', function () {
229+
process.getuid = () => 0;
230+
item.setUid(42);
231+
item.setGid(42);
232+
item.setMode(parseInt('0000', 8));
233+
assert.isTrue(item.canRead());
234+
});
223235
});
224236

225237
describe('#canWrite()', function () {
@@ -295,6 +307,14 @@ describe('Item', function () {
295307
item.setMode(parseInt('0777', 8));
296308
assert.isTrue(item.canWrite());
297309
});
310+
311+
it('always returns true if process runs as root', function () {
312+
process.getuid = () => 0;
313+
item.setUid(42);
314+
item.setGid(42);
315+
item.setMode(parseInt('0000', 8));
316+
assert.isTrue(item.canWrite());
317+
});
298318
});
299319

300320
describe('#canExecute()', function () {
@@ -370,6 +390,14 @@ describe('Item', function () {
370390
item.setMode(parseInt('0777', 8));
371391
assert.isTrue(item.canExecute());
372392
});
393+
394+
it('always returns true if process runs as root', function () {
395+
process.getuid = () => 0;
396+
item.setUid(42);
397+
item.setGid(42);
398+
item.setMode(parseInt('0000', 8));
399+
assert.isTrue(item.canExecute());
400+
});
373401
});
374402
}
375403
});

0 commit comments

Comments
 (0)