2014년 12월 3일 수요일

fs.fchmod on a socket

I'd like to make a UNIX domain socket world writable after I've chrooted. But I have two problems.

Using fs.open on a socket throws errno: -1, code: 'UNKNOWN'.

I've also tried to get a handle using net.connect:

var socket = net.connect(path);
var fd = socket._handle.fd;
fs.fchmod(fd, '666', ..

but this gives [Error: EINVAL, fchmod] errno: 18, code: 'EINVAL'

How can I get a file descriptor to a socket so that I can use fd.fchmod?



Permissions on Unix domain sockets are ignored, but set initially in the metadata by the process umask.



Aria, according to man 7 unix [1], what you wrote only applies for BSD-derived systems, and on Linux, socket permissions are honored as expected.

This is consistent with my own experience - I have a program (not using Node.js) that starts a socket then runs the chmod and chown commands on it, and they do have the desired effect.

as far as why you can't do this on Node.js... I'm not sure, there doesn't appear to be any special handling for sockets in the coreutils code.




I'm using umask 000 to make it world writable on creation, but AFAIK this creates a race condition, I only want the process to be listening on a world-writable socket after it's chrooted.

When I don't use a process umask of 000 I get an EACCES error when trying to write to the socket with another user (since it's 755).

I just read in chmod(2) "[EINVAL] fd refers to a socket, not to a file.". So with ignored you mean you can't chmod a socket after creation, and not that permissions are ignored when accessing the socket?

Is it possible to create a world writable socket and start listening after I've chrooted to /var/empty?

ps. I've read on SO socket permissions on unix are ignored, but I can confirm this is not the case on OS X, and unix(4) on OpenBSD states "Normal filesystem access-control mechanisms are also applied when referencing pathnames; e.g., the destination of a connect(2) or sendto(2) must be writable."



Correct: even mode 000, a socket can be connected to.

This is not my experience, like I said, when I don't use a process umask of 000 (i.e. 022) I get an EACCES error when trying to write to the socket with another user (since the socket is 755 and thus not world writable).



> I'd like to make a UNIX domain socket world writable after I've chrooted.
> But I have two problems.
>
> Using fs.open on a socket throws errno: -1, code: 'UNKNOWN'.
>
> I've also tried to get a handle using net.connect:
>
> var socket = net.connect(path);
> var fd = socket._handle.fd;
> fs.fchmod(fd, '666', ..
...

You can't do the things you tried at the system level, its not a node
limitation.

To create a unix domain socket and sets is mode atomically, you need
to set your umask
(http://nodejs.org/api/process.html#process_process_umask_mask).

To change the mode after-creation, use fs.chmod()
(http://nodejs.org/api/fs.html#fs_fs_chmod_path_mode_callback).

--
Job board: http://jobs.nodejs.org/
New group rules: https://gist.github.com/othiym23/9886289#file-moderation-policy-md
Old group rules: https://github.com/joyent/node/wiki/Mailing-List-Posting-Guidelines


댓글 없음:

댓글 쓰기