This repository has been archived by the owner on Dec 11, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathnsfork.c
52 lines (45 loc) · 1.61 KB
/
nsfork.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
/*
* nsfork.c - like fork, but the child process is in a new namespace
* Copyright 2011, Albert P. Tobey <[email protected]>
* https://github.com/tobert/nschroot
*
* This is free software; you can redistribute it and/or modify it under the
* terms of the Artistic License 2.0. See the file LICENSE for details.
*
* minimum linux kernel: v2.6.24
* execution requires root and/or CAP_SYS_ADMIN
*/
#include "config.h"
#include <unistd.h>
#include <sys/syscall.h>
#include <signal.h>
#include "nsfork.h"
/* extra_flags:
* set to 0 for regular nsfork, which leaves the new process in the same
* network namespace, but places everything else in a new ns
*
* CLONE_NEWNET - also create a new network namespace
* See also: clone(2)
*/
pid_t nsfork(int extra_flags)
{
/* kernel sys_fork only passes SIGCHLD, which is exactly what's desired here
*
* I did find userspace code implementing clone-based forks that passed
* CLONE_CHILD_SETTID but figure I want to be as close to regular fork() as
* possible but create a new namespace
* /usr/src/linux-2.6.37/arch/x86/kernel/process.c
*
* Also adding CLONE_IO to make it possible to implement a bit of a light
* vfork/popen. We need pipes to the opened process to capture its stdio.
*/
int clone_flags = extra_flags | CLONE_NEWNS | CLONE_NEWIPC | CLONE_NEWPID | CLONE_NEWUTS | SIGCHLD;
pid_t child_pid = 0;
#ifdef TESTING
child_pid = fork();
#else
// manual sys_clone behaves like fork() but allows flags to create a namespace
child_pid = syscall(SYS_clone, clone_flags, 0);
#endif
return child_pid;
}