From a956791f6995f9cfbeb21ffcf129125665bed298 Mon Sep 17 00:00:00 2001 From: Ben Noordhuis Date: Tue, 17 Feb 2015 22:53:21 +0100 Subject: [PATCH 1/2] src: fix typo in error message PR-URL: https://github.com/iojs/io.js/pull/875 Reviewed-By: Colin Ihrig Reviewed-By: Vladimir Kurchatkin --- src/node.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/node.cc b/src/node.cc index bffcd04cfd8b5e..48c93b8b6a8a61 100644 --- a/src/node.cc +++ b/src/node.cc @@ -1030,7 +1030,7 @@ Handle MakeCallback(Environment* env, try_catch.SetVerbose(false); env->async_hooks_pre_function()->Call(object, 0, nullptr); if (try_catch.HasCaught()) - FatalError("node:;MakeCallback", "pre hook threw"); + FatalError("node::MakeCallback", "pre hook threw"); try_catch.SetVerbose(true); } From b5f25a963cada60ada3230124585ad1fc9a1ad7a Mon Sep 17 00:00:00 2001 From: Ben Noordhuis Date: Wed, 18 Feb 2015 03:43:29 +0100 Subject: [PATCH 2/2] 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: https://github.com/iojs/io.js/pull/875 Reviewed-By: Colin Ihrig Reviewed-By: Vladimir Kurchatkin --- src/node.cc | 17 ++++++++++++++++- test/parallel/test-stdio-closed.js | 24 ++++++++++++++++++++++++ 2 files changed, 40 insertions(+), 1 deletion(-) create mode 100644 test/parallel/test-stdio-closed.js diff --git a/src/node.cc b/src/node.cc index 48c93b8b6a8a61..e060304bffc25c 100644 --- a/src/node.cc +++ b/src/node.cc @@ -3366,7 +3366,22 @@ inline void PlatformInit() { sigset_t sigmask; sigemptyset(&sigmask); sigaddset(&sigmask, SIGUSR1); - CHECK_EQ(0, pthread_sigmask(SIG_SETMASK, &sigmask, nullptr)); + const int err = pthread_sigmask(SIG_SETMASK, &sigmask, nullptr); + + // Make sure file descriptors 0-2 are valid before we start logging anything. + for (int fd = STDIN_FILENO; fd <= STDERR_FILENO; fd += 1) { + struct stat ignored; + if (fstat(fd, &ignored) == 0) + continue; + // Anything but EBADF means something is seriously wrong. We don't + // have to special-case EINTR, fstat() is not interruptible. + if (errno != EBADF) + abort(); + if (fd != open("/dev/null", O_RDWR)) + abort(); + } + + CHECK_EQ(err, 0); // Restore signal dispositions, the parent process may have changed them. struct sigaction act; diff --git a/test/parallel/test-stdio-closed.js b/test/parallel/test-stdio-closed.js new file mode 100644 index 00000000000000..fd081b8c11a798 --- /dev/null +++ b/test/parallel/test-stdio-closed.js @@ -0,0 +1,24 @@ +var common = require('../common'); +var assert = require('assert'); +var spawn = require('child_process').spawn; + +if (process.platform === 'win32') { + console.log('Skipping test, platform not supported.'); + return; +} + +if (process.argv[2] === 'child') { + process.stdout.write('stdout', function() { + process.stderr.write('stderr', function() { + process.exit(42); + }); + }); +} + +// Run the script in a shell but close stdout and stderr. +var cmd = '"' + process.execPath + '" "' + __filename + '" child 1>&- 2>&-'; +var proc = spawn('/bin/sh', ['-c', cmd], { stdio: 'inherit' }); + +proc.on('exit', common.mustCall(function(exitCode) { + assert.equal(exitCode, 42); +}));