Skip to content

Commit

Permalink
net: allow IPC servers be accessible by all
Browse files Browse the repository at this point in the history
Adds mappings to uv_pipe_chmod call by adding two new options to
listen call. This allows the IPC server pipe to be made readable or
writable by all users.

Fixes: nodejs#19154
  • Loading branch information
bzoz committed May 17, 2018
1 parent f9de6f5 commit 6d8b6dc
Show file tree
Hide file tree
Showing 5 changed files with 58 additions and 0 deletions.
8 changes: 8 additions & 0 deletions doc/api/net.md
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,10 @@ added: v0.11.14
* `backlog` {number} Common parameter of [`server.listen()`][]
functions.
* `exclusive` {boolean} **Default:** `false`
* `readableAll` {boolean} For IPC servers makes the pipe readable
for all users. **Default:** `false`
* `writableAll` {boolean} For IPC servers makes the pipe writable
for all users. **Default:** `false`
* `callback` {Function} Common parameter of [`server.listen()`][]
functions.
* Returns: {net.Server}
Expand All @@ -284,6 +288,10 @@ server.listen({
});
```

Starting an IPC server as root may cause the server path to be inaccessible for
unprivileged users. Using `readableAll` and `writableAll` will make the server
accessible for all users.

#### server.listen(path[, backlog][, callback])
<!-- YAML
added: v0.1.90
Expand Down
13 changes: 13 additions & 0 deletions lib/net.js
Original file line number Diff line number Diff line change
Expand Up @@ -1475,6 +1475,19 @@ Server.prototype.listen = function(...args) {
backlog = options.backlog || backlogFromArgs;
listenInCluster(this, pipeName, -1, -1,
backlog, undefined, options.exclusive);
let mode = 0;
if (options.readableAll === true)
mode |= PipeConstants.UV_READABLE;
if (options.writableAll === true)
mode |= PipeConstants.UV_WRITABLE;
if (mode !== 0) {
const err = this._handle.fchmod(mode);
if (err) {
this._handle.close();
this._handle = null;
throw errnoException(err, 'uv_pipe_chmod');
}
}
return this;
}

Expand Down
15 changes: 15 additions & 0 deletions src/pipe_wrap.cc
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,8 @@ void PipeWrap::Initialize(Local<Object> target,
env->SetProtoMethod(t, "setPendingInstances", SetPendingInstances);
#endif

env->SetProtoMethod(t, "fchmod", Fchmod);

target->Set(pipeString, t->GetFunction());
env->set_pipe_constructor_template(t);

Expand All @@ -114,6 +116,8 @@ void PipeWrap::Initialize(Local<Object> target,
NODE_DEFINE_CONSTANT(constants, SOCKET);
NODE_DEFINE_CONSTANT(constants, SERVER);
NODE_DEFINE_CONSTANT(constants, IPC);
NODE_DEFINE_CONSTANT(constants, UV_READABLE);
NODE_DEFINE_CONSTANT(constants, UV_WRITABLE);
target->Set(context,
FIXED_ONE_BYTE_STRING(env->isolate(), "constants"),
constants).FromJust();
Expand Down Expand Up @@ -184,6 +188,17 @@ void PipeWrap::SetPendingInstances(const FunctionCallbackInfo<Value>& args) {
#endif


void PipeWrap::Fchmod(const v8::FunctionCallbackInfo<v8::Value>& args) {
PipeWrap* wrap;
ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder());
CHECK(args[0]->IsInt32());
int mode = args[0].As<Int32>()->Value();
int err = uv_pipe_chmod(reinterpret_cast<uv_pipe_t*>(&wrap->handle_),
mode);
args.GetReturnValue().Set(err);
}


void PipeWrap::Listen(const FunctionCallbackInfo<Value>& args) {
PipeWrap* wrap;
ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder());
Expand Down
1 change: 1 addition & 0 deletions src/pipe_wrap.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ class PipeWrap : public ConnectionWrap<PipeWrap, uv_pipe_t> {
static void SetPendingInstances(
const v8::FunctionCallbackInfo<v8::Value>& args);
#endif
static void Fchmod(const v8::FunctionCallbackInfo<v8::Value>& args);
};


Expand Down
21 changes: 21 additions & 0 deletions test/parallel/test-net-server-listen-path.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

const common = require('../common');
const net = require('net');
const assert = require('assert');
const fs = require('fs');

const tmpdir = require('../common/tmpdir');
tmpdir.refresh();
Expand Down Expand Up @@ -48,3 +50,22 @@ function randomPipePath() {
net.createServer()
.listen({ path: handlePath }, closeServer());
}

// Test pipe chmod
{
const handlePath = randomPipePath();

const srv = net.createServer()
.listen({
path: handlePath,
readableAll: true,
writableAll: true
}, common.mustCall(() => {
if (process.platform !== 'win32') {
const mode = fs.statSync(handlePath).mode;
assert.ok(mode & fs.constants.S_IROTH !== 0);
assert.ok(mode & fs.constants.S_IWOTH !== 0);
}
srv.close();
}));
}

0 comments on commit 6d8b6dc

Please sign in to comment.