#include <iostream>
#include <fcntl.h>
#include <unistd.h>
#include <sys/mount.h>
#include <sys/wait.h>
using namespace std;
int main()
{
if (unshare(CLONE_NEWNS|CLONE_NEWCGROUP|CLONE_NEWUTS|CLONE_NEWIPC|CLONE_NEWPID) == -1){
perror("unshare");
exit(1);
}
int namespace_fd = open("/var/run/netns/afirefox", O_RDONLY|O_CLOEXEC);
if ((namespace_fd) == -1){
perror("open");
exit(1);
}
if (setns(namespace_fd, CLONE_NEWNET) == -1){
perror("setns");
exit(1);
}
if (close(namespace_fd) == -1){
perror("close");
exit(1);
}
if (mount("/proc/self/ns/net", "/var/run/netns/afirefox", "none", MS_BIND, NULL) == -1) {
perror("mount");
exit(1);
}
int pid = fork();
if (pid != 0) {
if (setresuid(-1, 1001, 1001) == -1){
perror("setresuid");
exit(1);
}
int status;
if (waitpid(-1, &status, 0) == -1){
perror("waitpid");
exit(1);
}
return status;
}
if (mount("none", "/", NULL, MS_PRIVATE|MS_REC, NULL) == -1) {
perror("mount");
exit(1);
}
if (chroot("/path/to/new/root/") == -1){
perror("chroot");
exit(1);
}
if (chdir("/") == -1){
perror("chdir");
exit(1);
}
if (mount("proc", "/proc", "proc", MS_NOSUID|MS_NODEV|MS_NOEXEC, NULL) == -1) {
perror("mount");
exit(1);
}
if (setresuid(-1, 1001, 1001) == -1){
perror("setresuid");
exit(1);
}
if (execlp("/bin/bash", "/bin/bash", NULL) == -1){
perror("execlp");
exit(1);
}
return 0;
}
Źródło: