Clone with CLONE_VM|CLONE_VFORK and call desired function.
This helper is aimed to be used functions, which require
to drop their capabilities, say, enter to less permissive
user_ns.

Signed-off-by: Kirill Tkhai <[email protected]>
---
 criu/include/util.h |    1 +
 criu/util.c         |   30 ++++++++++++++++++++++++++++++
 2 files changed, 31 insertions(+)

diff --git a/criu/include/util.h b/criu/include/util.h
index 969867b2d..c6429ce24 100644
--- a/criu/include/util.h
+++ b/criu/include/util.h
@@ -294,6 +294,7 @@ int run_tcp_server(bool daemon_mode, int *ask, int cfd, int 
sk);
 int setup_tcp_client(char *addr);
 int cr_set_root(int fd, int *old_root);
 int cr_restore_root(int fd);
+int call_in_child_process(int (*fn)(void *), void *arg);
 
 #define LAST_PID_PATH          "sys/kernel/ns_last_pid"
 #define PID_MAX_PATH           "sys/kernel/pid_max"
diff --git a/criu/util.c b/criu/util.c
index 91f1ffe01..0fb2b46eb 100644
--- a/criu/util.c
+++ b/criu/util.c
@@ -48,6 +48,7 @@
 #include "namespaces.h"
 #include "criu-log.h"
 
+#include "clone-noasan.h"
 #include "cr_options.h"
 #include "servicefd.h"
 #include "cr-service.h"
@@ -1340,3 +1341,32 @@ int cr_restore_root(int root)
 
        return ret;
 }
+
+int call_in_child_process(int (*fn)(void *), void *arg)
+{
+       int status, ret = -1;
+       pid_t pid;
+       /*
+        * Parent freezes till child exit, so child may use the same stack.
+        * No SIGCHLD flag, so it's not need to block signal.
+        */
+       pid = clone_noasan(fn, CLONE_VFORK | CLONE_VM | CLONE_FILES |
+                          CLONE_IO | CLONE_SIGHAND | CLONE_SYSVSEM, arg);
+       if (pid == -1) {
+               pr_perror("Can't clone");
+               return -1;
+       }
+       errno = 0;
+       if (waitpid(pid, &status, __WALL) != pid || !WIFEXITED(status) || 
WEXITSTATUS(status)) {
+               pr_err("Can't wait or bad status: errno=%d, status=%d", errno, 
status);
+               goto out;
+       }
+       ret = 0;
+       /*
+        * Child opened PROC_SELF for pid. If we create one more child
+        * with the same pid later, it will try to reuse this /proc/self.
+        */
+out:
+       close_pid_proc();
+       return ret;
+}

_______________________________________________
Devel mailing list
[email protected]
https://lists.openvz.org/mailman/listinfo/devel

Reply via email to