Skip to content

Commit b242248

Browse files
bzoztargos
authored andcommitted
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: #19154 PR-URL: #19472 Reviewed-By: Santiago Gimeno <santiago.gimeno@gmail.com> Reviewed-By: Anna Henningsen <anna@addaleax.net>
1 parent d2bcd55 commit b242248

5 files changed

Lines changed: 58 additions & 0 deletions

File tree

‎doc/api/net.md‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,10 @@ added: v0.11.14
260260
*`backlog` {number} Common parameter of [`server.listen()`][]
261261
functions.
262262
*`exclusive` {boolean} **Default:**`false`
263+
*`readableAll` {boolean} For IPC servers makes the pipe readable
264+
for all users. **Default:**`false`
265+
*`writableAll` {boolean} For IPC servers makes the pipe writable
266+
for all users. **Default:**`false`
263267
*`callback` {Function} Common parameter of [`server.listen()`][]
264268
functions.
265269
* Returns: {net.Server}
@@ -285,6 +289,10 @@ server.listen({
285289
});
286290
```
287291

292+
Starting an IPC server as root may cause the server path to be inaccessible for
293+
unprivileged users. Using `readableAll` and `writableAll` will make the server
294+
accessible for all users.
295+
288296
#### server.listen(path[, backlog][, callback])
289297
<!-- YAML
290298
added: v0.1.90

‎lib/net.js‎

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1475,6 +1475,19 @@ Server.prototype.listen = function(...args) {
14751475
backlog=options.backlog||backlogFromArgs;
14761476
listenInCluster(this,pipeName,-1,-1,
14771477
backlog,undefined,options.exclusive);
1478+
letmode=0;
1479+
if(options.readableAll===true)
1480+
mode|=PipeConstants.UV_READABLE;
1481+
if(options.writableAll===true)
1482+
mode|=PipeConstants.UV_WRITABLE;
1483+
if(mode!==0){
1484+
consterr=this._handle.fchmod(mode);
1485+
if(err){
1486+
this._handle.close();
1487+
this._handle=null;
1488+
throwerrnoException(err,'uv_pipe_chmod');
1489+
}
1490+
}
14781491
returnthis;
14791492
}
14801493

‎src/pipe_wrap.cc‎

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,8 @@ void PipeWrap::Initialize(Local<Object> target,
9898
env->SetProtoMethod(t, "setPendingInstances", SetPendingInstances);
9999
#endif
100100

101+
env->SetProtoMethod(t, "fchmod", Fchmod);
102+
101103
target->Set(pipeString, t->GetFunction());
102104
env->set_pipe_constructor_template(t);
103105

@@ -114,6 +116,8 @@ void PipeWrap::Initialize(Local<Object> target,
114116
NODE_DEFINE_CONSTANT(constants, SOCKET);
115117
NODE_DEFINE_CONSTANT(constants, SERVER);
116118
NODE_DEFINE_CONSTANT(constants, IPC);
119+
NODE_DEFINE_CONSTANT(constants, UV_READABLE);
120+
NODE_DEFINE_CONSTANT(constants, UV_WRITABLE);
117121
target->Set(context,
118122
FIXED_ONE_BYTE_STRING(env->isolate(), "constants"),
119123
constants).FromJust();
@@ -184,6 +188,17 @@ void PipeWrap::SetPendingInstances(const FunctionCallbackInfo<Value>& args) {
184188
#endif
185189

186190

191+
voidPipeWrap::Fchmod(const v8::FunctionCallbackInfo<v8::Value>& args) {
192+
PipeWrap* wrap;
193+
ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder());
194+
CHECK(args[0]->IsInt32());
195+
int mode = args[0].As<Int32>()->Value();
196+
int err = uv_pipe_chmod(reinterpret_cast<uv_pipe_t*>(&wrap->handle_),
197+
mode);
198+
args.GetReturnValue().Set(err);
199+
}
200+
201+
187202
voidPipeWrap::Listen(const FunctionCallbackInfo<Value>& args) {
188203
PipeWrap* wrap;
189204
ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder());

‎src/pipe_wrap.h‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ class PipeWrap : public ConnectionWrap<PipeWrap, uv_pipe_t> {
6363
staticvoidSetPendingInstances(
6464
const v8::FunctionCallbackInfo<v8::Value>& args);
6565
#endif
66+
staticvoidFchmod(const v8::FunctionCallbackInfo<v8::Value>& args);
6667
};
6768

6869

‎test/parallel/test-net-server-listen-path.js‎

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
constcommon=require('../common');
44
constnet=require('net');
5+
constassert=require('assert');
6+
constfs=require('fs');
57

68
consttmpdir=require('../common/tmpdir');
79
tmpdir.refresh();
@@ -48,3 +50,22 @@ function randomPipePath() {
4850
net.createServer()
4951
.listen({path: handlePath},closeServer());
5052
}
53+
54+
// Test pipe chmod
55+
{
56+
consthandlePath=randomPipePath();
57+
58+
constsrv=net.createServer()
59+
.listen({
60+
path: handlePath,
61+
readableAll: true,
62+
writableAll: true
63+
},common.mustCall(()=>{
64+
if(process.platform!=='win32'){
65+
constmode=fs.statSync(handlePath).mode;
66+
assert.ok(mode&fs.constants.S_IROTH!==0);
67+
assert.ok(mode&fs.constants.S_IWOTH!==0);
68+
}
69+
srv.close();
70+
}));
71+
}

0 commit comments

Comments
 (0)