Skip to content

Commit b5f25a9

Browse files
committed
src: ensure that file descriptors 0-2 are valid
Check that stdin, stdout and stderr map to open file descriptors and remap them to /dev/null if that isn't the case. Protects against information leaks or worse when io.js is started with closed stdio file descriptors. PR-URL: #875 Reviewed-By: Colin Ihrig <[email protected]> Reviewed-By: Vladimir Kurchatkin <[email protected]>
1 parent a956791 commit b5f25a9

File tree

2 files changed

+40
-1
lines changed

2 files changed

+40
-1
lines changed

src/node.cc

+16-1
Original file line numberDiff line numberDiff line change
@@ -3366,7 +3366,22 @@ inline void PlatformInit() {
33663366
sigset_t sigmask;
33673367
sigemptyset(&sigmask);
33683368
sigaddset(&sigmask, SIGUSR1);
3369-
CHECK_EQ(0, pthread_sigmask(SIG_SETMASK, &sigmask, nullptr));
3369+
const int err = pthread_sigmask(SIG_SETMASK, &sigmask, nullptr);
3370+
3371+
// Make sure file descriptors 0-2 are valid before we start logging anything.
3372+
for (int fd = STDIN_FILENO; fd <= STDERR_FILENO; fd += 1) {
3373+
struct stat ignored;
3374+
if (fstat(fd, &ignored) == 0)
3375+
continue;
3376+
// Anything but EBADF means something is seriously wrong. We don't
3377+
// have to special-case EINTR, fstat() is not interruptible.
3378+
if (errno != EBADF)
3379+
abort();
3380+
if (fd != open("/dev/null", O_RDWR))
3381+
abort();
3382+
}
3383+
3384+
CHECK_EQ(err, 0);
33703385

33713386
// Restore signal dispositions, the parent process may have changed them.
33723387
struct sigaction act;

test/parallel/test-stdio-closed.js

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
var common = require('../common');
2+
var assert = require('assert');
3+
var spawn = require('child_process').spawn;
4+
5+
if (process.platform === 'win32') {
6+
console.log('Skipping test, platform not supported.');
7+
return;
8+
}
9+
10+
if (process.argv[2] === 'child') {
11+
process.stdout.write('stdout', function() {
12+
process.stderr.write('stderr', function() {
13+
process.exit(42);
14+
});
15+
});
16+
}
17+
18+
// Run the script in a shell but close stdout and stderr.
19+
var cmd = '"' + process.execPath + '" "' + __filename + '" child 1>&- 2>&-';
20+
var proc = spawn('/bin/sh', ['-c', cmd], { stdio: 'inherit' });
21+
22+
proc.on('exit', common.mustCall(function(exitCode) {
23+
assert.equal(exitCode, 42);
24+
}));

0 commit comments

Comments
 (0)