12 #include <sys/mount.h>
23 #define CLONE_NEWUSER 0x10000000
26 #define CLONE_NEWPID 0x20000000
33 #define CVMFS_HAS_UNSHARE 1
34 #ifdef __GLIBC_MINOR__
35 #if __GLIBC_MINOR__ < 4
36 #undef CVMFS_HAS_UNSHARE
49 const int fd = open(
"/proc/sys/kernel/unprivileged_userns_clone", O_RDONLY);
62 #ifdef CVMFS_HAS_UNSHARE
70 std::string uid_map =
StringifyInt(map_uid_to) +
" " + uid_str +
" 1";
71 std::string gid_map =
StringifyInt(map_gid_to) +
" " + gid_str +
" 1";
75 fd = open(
"/proc/self/setgroups", O_WRONLY);
78 nbytes = write(fd,
"deny", 4);
83 fd = open(
"/proc/self/uid_map", O_WRONLY);
86 nbytes = write(fd, uid_map.data(), uid_map.length());
88 if (nbytes != static_cast<ssize_t>(uid_map.length()))
91 fd = open(
"/proc/self/gid_map", O_WRONLY);
94 nbytes = write(fd, gid_map.data(), gid_map.length());
96 if (nbytes != static_cast<ssize_t>(gid_map.length()))
106 bool BindMount(
const std::string &from,
const std::string &to) {
110 const int rvi = mount(from.c_str(), to.c_str(),
"", MS_BIND |
MS_REC, NULL);
120 const int rvi = mount(
"proc", to.c_str(),
"proc", 0, NULL);
127 #ifdef CVMFS_HAS_UNSHARE
130 int rvi = unshare(CLONE_NEWNS);
134 rvi = chdir(cwd.c_str());
142 #ifdef CVMFS_HAS_UNSHARE
145 static void Reaper(
int , siginfo_t * ,
void * ) {
147 const pid_t retval = waitpid(-1, NULL, WNOHANG);
163 #ifdef CVMFS_HAS_UNSHARE
184 max_fd =
static_cast<int>(sysconf(_SC_OPEN_MAX));
185 for (
int fd = 0; fd < max_fd; fd++) {
186 if (fd != pipe_parent[1])
190 pid_t parent_pid = getpid();
191 SafeWrite(pipe_parent[1], &parent_pid,
sizeof(parent_pid));
192 SafeWrite(pipe_parent[1], &pid,
sizeof(pid));
194 rvi = waitpid(pid, &status, 0);
196 if (WIFEXITED(status))
197 exit(WEXITSTATUS(status));
201 close(pipe_parent[1]);
202 if (fd_parent != NULL)
203 *fd_parent = pipe_parent[0];
208 memset(&sa, 0,
sizeof(sa));
210 sa.sa_flags = SA_SIGINFO;
211 sigfillset(&sa.sa_mask);
212 rvi = sigaction(SIGCHLD, &sa, NULL);
215 rvi = mount(
"",
"/proc",
"proc", 0, NULL);
bool CreateMountNamespace()
const int kNsFeatureUserAvailable
const int kNsFeatureMount
const int kNsFeatureUserEnabled
bool SafeWrite(int fd, const void *buf, size_t nbyte)
assert((mem||(size==0))&&"Out Of Memory")
void MakePipe(int pipe_fd[2])
bool SymlinkExists(const std::string &path)
ssize_t SafeRead(int fd, void *buf, size_t nbyte)
static void Reaper(int, siginfo_t *, void *)
NamespaceFailures CreateUserNamespace(uid_t map_uid_to, gid_t map_gid_to)
bool ProcMount(const std::string &to)
string StringifyInt(const int64_t value)
int CheckNamespaceFeatures()
bool CreatePidNamespace(int *fd_parent)
bool BindMount(const std::string &from, const std::string &to)
std::string GetCurrentWorkingDirectory()