payload.exec_function = exec_function;
payload.exec_payload = exec_payload;
- pid = lxc_raw_clone(CLONE_PARENT);
+ pid = lxc_raw_clone(CLONE_PARENT, NULL);
if (pid < 0) {
SYSERROR("Failed to clone attached process");
shutdown(ipc_sockets[1], SHUT_RDWR);
d.p[1] = p[1];
/* Clone child in new user namespace. */
- pid = lxc_raw_clone_cb(run_userns_fn, &d, CLONE_NEWUSER);
+ pid = lxc_raw_clone_cb(run_userns_fn, &d, CLONE_NEWUSER, NULL);
if (pid < 0) {
ERROR("Failed to clone process in new user namespace");
goto on_error;
* The nice thing about this is that we get fork() behavior. That is
* lxc_raw_clone() returns 0 in the child and the child pid in the parent.
*/
-__returns_twice pid_t lxc_raw_clone(unsigned long flags)
+__returns_twice pid_t lxc_raw_clone(unsigned long flags, int *pidfd)
{
/*
* These flags don't interest at all so we don't jump through any hoops
/* On s390/s390x and cris the order of the first and second arguments
* of the system call is reversed.
*/
- return syscall(__NR_clone, NULL, flags | SIGCHLD);
+ return syscall(__NR_clone, NULL, flags | SIGCHLD, pidfd);
#elif defined(__sparc__) && defined(__arch64__)
{
/*
register long g1 asm("g1") = __NR_clone;
register long o0 asm("o0") = flags | SIGCHLD;
register long o1 asm("o1") = 0; /* is parent/child indicator */
+ register long o2 asm("o2") = (unsigned long)pidfd;
long is_error, retval, in_child;
pid_t child_pid;
* full register.
*/
"addx %%g0, 0, %g1"
- : "=r"(g1), "=r"(o0), "=r"(o1) /* outputs */
- : "r"(g1), "r"(o0), "r"(o1) /* inputs */
- : "%cc"); /* clobbers */
+ : "=r"(g1), "=r"(o0), "=r"(o1), "=r"(o2) /* outputs */
+ : "r"(g1), "r"(o0), "r"(o1), "r"(o2) /* inputs */
+ : "%cc"); /* clobbers */
is_error = g1;
retval = o0;
}
#elif defined(__ia64__)
/* On ia64 the stack and stack size are passed as separate arguments. */
- return syscall(__NR_clone, flags | SIGCHLD, NULL, prctl_arg(0));
+ return syscall(__NR_clone, flags | SIGCHLD, NULL, prctl_arg(0), pidfd);
#else
- return syscall(__NR_clone, flags | SIGCHLD, NULL);
+ return syscall(__NR_clone, flags | SIGCHLD, NULL, pidfd);
#endif
}
-pid_t lxc_raw_clone_cb(int (*fn)(void *), void *args, unsigned long flags)
+pid_t lxc_raw_clone_cb(int (*fn)(void *), void *args, unsigned long flags,
+ int *pidfd)
{
pid_t pid;
- pid = lxc_raw_clone(flags);
+ pid = lxc_raw_clone(flags, pidfd);
if (pid < 0)
return -1;
#include <sys/syscall.h>
#include <unistd.h>
+/* clone */
+#ifndef CLONE_PIDFD
+#define CLONE_PIDFD 0x00001000
+#endif
+
/*
* lxc_raw_clone() - create a new process
*
* - must call lxc_raw_getpid():
* The child must use lxc_raw_getpid() to retrieve its pid.
*/
-extern pid_t lxc_raw_clone(unsigned long flags);
+extern pid_t lxc_raw_clone(unsigned long flags, int *pidfd);
/*
* lxc_raw_clone_cb() - create a new process
* All other comments that apply to lxc_raw_clone() apply to lxc_raw_clone_cb()
* as well.
*/
-extern pid_t lxc_raw_clone_cb(int (*fn)(void *), void *args, unsigned long flags);
+extern pid_t lxc_raw_clone_cb(int (*fn)(void *), void *args,
+ unsigned long flags, int *pidfd);
extern int lxc_raw_execveat(int dirfd, const char *pathname, char *const argv[],
char *const envp[], int flags);
flags = handler->ns_on_clone_flags;
flags |= CLONE_PARENT;
- handler->pid = lxc_raw_clone_cb(do_start, handler, flags);
+ handler->pid = lxc_raw_clone_cb(do_start, handler, flags, NULL);
if (handler->pid < 0)
return -1;
}
} else {
handler->pid = lxc_raw_clone_cb(do_start, handler,
- handler->ns_on_clone_flags);
+ handler->ns_on_clone_flags, NULL);
}
if (handler->pid < 0) {
SYSERROR(LXC_CLONE_ERROR);
return -1;
}
- child = lxc_raw_clone(0);
+ child = lxc_raw_clone(0, NULL);
if (child < 0) {
close(pipefd[0]);
close(pipefd[1]);
pid_t pid;
int flags = 0;
- pid = lxc_raw_clone(CLONE_PARENT_SETTID);
+ pid = lxc_raw_clone(CLONE_PARENT_SETTID, NULL);
if (pid >= 0 || pid != -EINVAL) {
lxc_error("%s\n", "Calling lxc_raw_clone(CLONE_PARENT_SETTID) "
"should not be possible");
exit(EXIT_FAILURE);
}
- pid = lxc_raw_clone(CLONE_CHILD_SETTID);
+ pid = lxc_raw_clone(CLONE_CHILD_SETTID, NULL);
if (pid >= 0 || pid != -EINVAL) {
lxc_error("%s\n", "Calling lxc_raw_clone(CLONE_CHILD_SETTID) "
"should not be possible");
exit(EXIT_FAILURE);
}
- pid = lxc_raw_clone(CLONE_CHILD_CLEARTID);
+ pid = lxc_raw_clone(CLONE_CHILD_CLEARTID, NULL);
if (pid >= 0 || pid != -EINVAL) {
lxc_error("%s\n", "Calling lxc_raw_clone(CLONE_CHILD_CLEARTID) "
"should not be possible");
exit(EXIT_FAILURE);
}
- pid = lxc_raw_clone(CLONE_SETTLS);
+ pid = lxc_raw_clone(CLONE_SETTLS, NULL);
if (pid >= 0 || pid != -EINVAL) {
lxc_error("%s\n", "Calling lxc_raw_clone(CLONE_SETTLS) should "
"not be possible");
exit(EXIT_FAILURE);
}
- pid = lxc_raw_clone(CLONE_VM);
+ pid = lxc_raw_clone(CLONE_VM, NULL);
if (pid >= 0 || pid != -EINVAL) {
lxc_error("%s\n", "Calling lxc_raw_clone(CLONE_VM) should "
"not be possible");
exit(EXIT_FAILURE);
}
- pid = lxc_raw_clone(0);
+ pid = lxc_raw_clone(0, NULL);
if (pid < 0) {
lxc_error("%s\n", "Failed to call lxc_raw_clone(0)");
exit(EXIT_FAILURE);
exit(EXIT_FAILURE);
}
- pid = lxc_raw_clone(0);
+ pid = lxc_raw_clone(0, NULL);
if (pid < 0) {
lxc_error("%s\n", "Failed to call lxc_raw_clone(0)");
exit(EXIT_FAILURE);
flags |= CLONE_NEWPID;
flags |= CLONE_NEWUTS;
- pid = lxc_raw_clone(flags);
+ pid = lxc_raw_clone(flags, NULL);
if (pid < 0) {
lxc_error("%s\n", "Failed to call lxc_raw_clone(CLONE_NEWUSER "
"| CLONE_NEWCGROUP | CLONE_NEWNS | "
exit(EXIT_FAILURE);
}
- pid = lxc_raw_clone(flags);
+ pid = lxc_raw_clone(flags, NULL);
if (pid < 0) {
lxc_error("%s\n", "Failed to call lxc_raw_clone(CLONE_NEWUSER "
"| CLONE_NEWCGROUP | CLONE_NEWNS | "
exit(EXIT_FAILURE);
}
- pid = lxc_raw_clone(CLONE_VFORK);
+ pid = lxc_raw_clone(CLONE_VFORK, NULL);
if (pid < 0) {
lxc_error("%s\n", "Failed to call lxc_raw_clone(CLONE_VFORK);");
exit(EXIT_FAILURE);
exit(EXIT_FAILURE);
}
- pid = lxc_raw_clone(CLONE_VFORK);
+ pid = lxc_raw_clone(CLONE_VFORK, NULL);
if (pid < 0) {
lxc_error("%s\n", "Failed to call lxc_raw_clone(CLONE_VFORK);");
exit(EXIT_FAILURE);
exit(EXIT_FAILURE);
}
- pid = lxc_raw_clone(CLONE_FILES);
+ pid = lxc_raw_clone(CLONE_FILES, NULL);
if (pid < 0) {
lxc_error("%s\n", "Failed to call lxc_raw_clone(CLONE_FILES);");
exit(EXIT_FAILURE);
exit(EXIT_FAILURE);
}
- pid = lxc_raw_clone(CLONE_FILES);
+ pid = lxc_raw_clone(CLONE_FILES, NULL);
if (pid < 0) {
lxc_error("%s\n", "Failed to call lxc_raw_clone(CLONE_FILES);");
exit(EXIT_FAILURE);