net: allow IPC servers be accessible by all
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: https://github.com/nodejs/node/issues/19154 PR-URL: https://github.com/nodejs/node/pull/19472 Reviewed-By: Santiago Gimeno <santiago.gimeno@gmail.com> Reviewed-By: Anna Henningsen <anna@addaleax.net>
This commit is contained in:
parent
03043e290a
commit
531b4bedca
@ -260,6 +260,10 @@ added: v0.11.14
|
|||||||
* `backlog` {number} Common parameter of [`server.listen()`][]
|
* `backlog` {number} Common parameter of [`server.listen()`][]
|
||||||
functions.
|
functions.
|
||||||
* `exclusive` {boolean} **Default:** `false`
|
* `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()`][]
|
* `callback` {Function} Common parameter of [`server.listen()`][]
|
||||||
functions.
|
functions.
|
||||||
* Returns: {net.Server}
|
* Returns: {net.Server}
|
||||||
@ -285,6 +289,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])
|
#### server.listen(path[, backlog][, callback])
|
||||||
<!-- YAML
|
<!-- YAML
|
||||||
added: v0.1.90
|
added: v0.1.90
|
||||||
|
13
lib/net.js
13
lib/net.js
@ -1475,6 +1475,19 @@ Server.prototype.listen = function(...args) {
|
|||||||
backlog = options.backlog || backlogFromArgs;
|
backlog = options.backlog || backlogFromArgs;
|
||||||
listenInCluster(this, pipeName, -1, -1,
|
listenInCluster(this, pipeName, -1, -1,
|
||||||
backlog, undefined, options.exclusive);
|
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;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -98,6 +98,8 @@ void PipeWrap::Initialize(Local<Object> target,
|
|||||||
env->SetProtoMethod(t, "setPendingInstances", SetPendingInstances);
|
env->SetProtoMethod(t, "setPendingInstances", SetPendingInstances);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
env->SetProtoMethod(t, "fchmod", Fchmod);
|
||||||
|
|
||||||
target->Set(pipeString, t->GetFunction());
|
target->Set(pipeString, t->GetFunction());
|
||||||
env->set_pipe_constructor_template(t);
|
env->set_pipe_constructor_template(t);
|
||||||
|
|
||||||
@ -114,6 +116,8 @@ void PipeWrap::Initialize(Local<Object> target,
|
|||||||
NODE_DEFINE_CONSTANT(constants, SOCKET);
|
NODE_DEFINE_CONSTANT(constants, SOCKET);
|
||||||
NODE_DEFINE_CONSTANT(constants, SERVER);
|
NODE_DEFINE_CONSTANT(constants, SERVER);
|
||||||
NODE_DEFINE_CONSTANT(constants, IPC);
|
NODE_DEFINE_CONSTANT(constants, IPC);
|
||||||
|
NODE_DEFINE_CONSTANT(constants, UV_READABLE);
|
||||||
|
NODE_DEFINE_CONSTANT(constants, UV_WRITABLE);
|
||||||
target->Set(context,
|
target->Set(context,
|
||||||
FIXED_ONE_BYTE_STRING(env->isolate(), "constants"),
|
FIXED_ONE_BYTE_STRING(env->isolate(), "constants"),
|
||||||
constants).FromJust();
|
constants).FromJust();
|
||||||
@ -184,6 +188,17 @@ void PipeWrap::SetPendingInstances(const FunctionCallbackInfo<Value>& args) {
|
|||||||
#endif
|
#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) {
|
void PipeWrap::Listen(const FunctionCallbackInfo<Value>& args) {
|
||||||
PipeWrap* wrap;
|
PipeWrap* wrap;
|
||||||
ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder());
|
ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder());
|
||||||
|
@ -63,6 +63,7 @@ class PipeWrap : public ConnectionWrap<PipeWrap, uv_pipe_t> {
|
|||||||
static void SetPendingInstances(
|
static void SetPendingInstances(
|
||||||
const v8::FunctionCallbackInfo<v8::Value>& args);
|
const v8::FunctionCallbackInfo<v8::Value>& args);
|
||||||
#endif
|
#endif
|
||||||
|
static void Fchmod(const v8::FunctionCallbackInfo<v8::Value>& args);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
const common = require('../common');
|
const common = require('../common');
|
||||||
const net = require('net');
|
const net = require('net');
|
||||||
|
const assert = require('assert');
|
||||||
|
const fs = require('fs');
|
||||||
|
|
||||||
const tmpdir = require('../common/tmpdir');
|
const tmpdir = require('../common/tmpdir');
|
||||||
tmpdir.refresh();
|
tmpdir.refresh();
|
||||||
@ -48,3 +50,22 @@ function randomPipePath() {
|
|||||||
net.createServer()
|
net.createServer()
|
||||||
.listen({ path: handlePath }, closeServer());
|
.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();
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user