Skip to content

Commit

Permalink
net: add fd protection, fix #3604
Browse files Browse the repository at this point in the history
  • Loading branch information
pmq20 committed Nov 3, 2015
1 parent be65f5f commit e72c094
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 0 deletions.
1 change: 1 addition & 0 deletions lib/net.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ const exceptionWithHostPort = util._exceptionWithHostPort;
function noop() {}

function createHandle(fd) {
if (TTYWrap.fdProtected(fd)) throw new Error('fd is being protected');
var type = TTYWrap.guessHandleType(fd);
if (type === 'PIPE') return new Pipe();
if (type === 'TCP') return new TCP();
Expand Down
15 changes: 15 additions & 0 deletions src/tty_wrap.cc
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ void TTYWrap::Initialize(Local<Object> target,

env->SetMethod(target, "isTTY", IsTTY);
env->SetMethod(target, "guessHandleType", GuessHandleType);
env->SetMethod(target, "fdProtected", FdProtected);

target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "TTY"), t->GetFunction());
env->set_tty_constructor_template(t);
Expand Down Expand Up @@ -78,6 +79,20 @@ void TTYWrap::GuessHandleType(const FunctionCallbackInfo<Value>& args) {
args.GetReturnValue().Set(OneByteString(env->isolate(), type));
}

void TTYWrap::FdProtected(const FunctionCallbackInfo<Value>& args) {
Environment* env = Environment::GetCurrent(args);
int32_t fd = args[0]->Int32Value();
CHECK_GE(fd, 0);

uv_loop_t* loop = env->event_loop();
bool ret = false;

if (static_cast<unsigned>(fd) < loop->nwatchers &&
loop->watchers[fd] != NULL)
ret = true;

args.GetReturnValue().Set(ret);
}

void TTYWrap::IsTTY(const FunctionCallbackInfo<Value>& args) {
int fd = args[0]->Int32Value();
Expand Down
1 change: 1 addition & 0 deletions src/tty_wrap.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ class TTYWrap : public StreamWrap {
bool readable);

static void GuessHandleType(const v8::FunctionCallbackInfo<v8::Value>& args);
static void FdProtected(const v8::FunctionCallbackInfo<v8::Value>& args);
static void IsTTY(const v8::FunctionCallbackInfo<v8::Value>& args);
static void GetWindowSize(const v8::FunctionCallbackInfo<v8::Value>& args);
static void SetRawMode(const v8::FunctionCallbackInfo<v8::Value>& args);
Expand Down
25 changes: 25 additions & 0 deletions test/parallel/test-net-socket-fd-protection.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
'use strict';
const common = require('../common');
const assert = require('assert');
const net = require('net');

var will_throw = function() {
var errors = [];
[ 3, 4, 5, 6, 7, 8, 9 ].forEach(function(fd) {
try {
var stream = new net.Socket({
fd: fd,
readable: false,
writable: true
});
stream.on('error', function() {});
stream.write('might crash');
} catch (e) {
errors.push(e);
}
});
throw errors;
};

// Should throw instead of crash
assert.throws(will_throw, /fd is being protected/);

0 comments on commit e72c094

Please sign in to comment.