--
Job Board: http://jobs.nodejs.org/
Posting guidelines: https://github.com/joyent/node/wiki/Mailing-List-Posting-Guidelines
You received this message because you are subscribed to the Google
Groups "nodejs" group.
To post to this group, send email to nod...@googlegroups.com
To unsubscribe from this group, send email to
nodejs+un...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/nodejs?hl=en?hl=en
It's there:
require('child_process').spawn(cmd, args, {setsid:true});
http://nodejs.org/docs/latest/api/child_processes.html#child_process.spawn
Added and documented in January of this year. Aeons ago on node's time scale. :)
> Does it work on the new child_process.fork() too?
Yep, fork() is just a thin wrapper around spawn().
>> require('child_process').spawn(cmd, args, {setsid:true});Added and documented in January of this year. Aeons ago on node's time scale. :)
>>
>> http://nodejs.org/docs/latest/api/child_processes.html#child_process.spawn
>
> Ooh, is that new?
Yep, fork() is just a thin wrapper around spawn().
> Does it work on the new child_process.fork() too?
On Unices, fork() in multi-threaded programs has awful semantics and
behaviour (google pthread_atfork or fork+epoll or open+FD_CLOEXEC to
see what I mean), that's why we execve() into another process as
quickly as possible. It's a kind of damage control.
The core issue is that fork() opens up a race window in multi-threaded
programs. Consider this single-threaded program running as root:
a. fd = open("/etc/passwd", O_RDWR);
b. fcntl(fd, F_SETFD, FD_CLOEXEC | flags);
c. fork() and drop privileges
d. execve("malicious-program")
No problem there. Now consider the same scenario in a multi-threaded program.
Thread 1:
a. fd = open("/etc/passwd", O_RDWR);
b. fcntl(fd, F_SETFD, FD_CLOEXEC | flags);
Thread 2:
a. fork() and drop privileges
b. execve("malicious-program")
If the call to fork() in 2a runs right between 1a and 1b, the file
descriptor will leak to the new process and - since open file
descriptors survive execve() - to the malicious program.
Linux has open() and socket() calls that lets you create close-on-exec
file descriptors atomically (you pass O_CLOEXEC in the flags arg) but
other Unices don't have such facilities.
On Fri, Jul 15, 2011 at 22:15, <hel...@gmail.com> wrote:The core issue is that fork() opens up a race window in multi-threaded
> Hmmm. I fork in my libev code (admittedly in perl) and it works fine. Guess it should be tried in a library though - have the node devs tried it so I'm not wasting my time?
programs. Consider this single-threaded program running as root:
a. fd = open("/etc/passwd", O_RDWR);
b. fcntl(fd, F_SETFD, FD_CLOEXEC | flags);
c. fork() and drop privileges
d. execve("malicious-program")
No problem there. Now consider the same scenario in a multi-threaded program.
Thread 1:
a. fd = open("/etc/passwd", O_RDWR);
b. fcntl(fd, F_SETFD, FD_CLOEXEC | flags);
Thread 2:
a. fork() and drop privileges
b. execve("malicious-program")
If the call to fork() in 2a runs right between 1a and 1b, the file
descriptor will leak to the new process and - since open file
descriptors survive execve() - to the malicious program.
Heaven save us from literal minded people! That example wasn't about
node but fork() in general.
Anyway, it's never going to happen. We need a clean slate after
forking for reasons pointed out in my previous-previous post.
Anyway, it's never going to happen. We need a clean slate after
forking for reasons pointed out in my previous-previous post.
We're not binding fork because Windows doesn't have it. We do not
consider the emulation hack acceptable.
Also all of the reasons Ben mentioned.
Also the first GC compact you hit will negate any COW win you had.