about summary refs log tree commit diff
diff options
context:
space:
mode:
authorLaurent Bercot <ska-skaware@skarnet.org>2024-09-12 11:53:13 +0000
committerLaurent Bercot <ska@appnovation.com>2024-09-12 11:53:13 +0000
commitf867414f4e1f8115d1c9796f8f91677673739368 (patch)
treee350efd8dff46f8f4adfc758d9f4bb292b0622ec
parenta7973043c92dc0f9d083e600142a47ce6dd1c9f6 (diff)
downloadskalibs-master.tar.gz
skalibs-master.tar.xz
skalibs-master.zip
Add sysdep for CLONE_NEWPID and fork_newpid function HEAD master
Signed-off-by: Laurent Bercot <ska@appnovation.com>
-rwxr-xr-xconfigure1
-rw-r--r--package/deps.mak1
-rw-r--r--src/include/skalibs/posixplz.h1
-rw-r--r--src/libposixplz/fork_newpid.c67
-rw-r--r--src/sysdeps/tryclonenewpid.c36
5 files changed, 106 insertions, 0 deletions
diff --git a/configure b/configure
index b54c2fc..72d95ab 100755
--- a/configure
+++ b/configure
@@ -659,6 +659,7 @@ choose cl explicit_bzero 'explicit_bzero()'
 choose cl getrandom 'getrandom()'
 choose cl grndinsecure 'GRND_INSECURE'
 choose cl chroot 'chroot()'
+choose cl clonenewpid 'clone3() with CLONE_NEWPID'
 choose cl posixspawnsetsid 'POSIX_SPAWN_SETSID' $spawn_lib
 choose cl posixspawnsetsidnp 'POSIX_SPAWN_SETSID_NP' $spawn_lib
 choose cl posixspawnchdir 'posix_spawn_file_actions_addchdir()' $spawn_lib
diff --git a/package/deps.mak b/package/deps.mak
index e88a469..6edc71f 100644
--- a/package/deps.mak
+++ b/package/deps.mak
@@ -171,6 +171,7 @@ src/libposixplz/doublefork.o src/libposixplz/doublefork.lo: src/libposixplz/doub
 src/libposixplz/execvep.o src/libposixplz/execvep.lo: src/libposixplz/execvep.c src/libposixplz/posixplz-internal.h src/include/skalibs/posixplz.h
 src/libposixplz/execvep_internal.o src/libposixplz/execvep_internal.lo: src/libposixplz/execvep_internal.c src/include/skalibs/bytestr.h src/include/skalibs/posixplz.h
 src/libposixplz/execvep_loose.o src/libposixplz/execvep_loose.lo: src/libposixplz/execvep_loose.c src/libposixplz/posixplz-internal.h src/include/skalibs/posixplz.h
+src/libposixplz/fork_newpid.o src/libposixplz/fork_newpid.lo: src/libposixplz/fork_newpid.c src/include/skalibs/nonposix.h src/include/skalibs/sysdeps.h src/include/skalibs/uint64.h
 src/libposixplz/getpeereid.o src/libposixplz/getpeereid.lo: src/libposixplz/getpeereid.c src/include/skalibs/nonposix.h src/include/skalibs/posixplz.h src/include/skalibs/sysdeps.h
 src/libposixplz/memmem.o src/libposixplz/memmem.lo: src/libposixplz/memmem.c src/include/skalibs/posixplz.h src/include/skalibs/sysdeps.h
 src/libposixplz/mkbtemp.o src/libposixplz/mkbtemp.lo: src/libposixplz/mkbtemp.c src/include/skalibs/djbunix.h src/include/skalibs/posixplz.h
diff --git a/src/include/skalibs/posixplz.h b/src/include/skalibs/posixplz.h
index daf9cdd..c990379 100644
--- a/src/include/skalibs/posixplz.h
+++ b/src/include/skalibs/posixplz.h
@@ -37,6 +37,7 @@ extern void execvep_loose (char const *, char const *const *, char const *const
 extern void unlink_void (char const *) ;
 extern void munmap_void (void *, size_t) ;
 extern pid_t doublefork (void) ;
+extern pid_t fork_newpid (void) ;
 extern int touch (char const *) ;
 
 extern int mkfiletemp (char *, create_func_ref, mode_t, void *) ;
diff --git a/src/libposixplz/fork_newpid.c b/src/libposixplz/fork_newpid.c
new file mode 100644
index 0000000..7887b53
--- /dev/null
+++ b/src/libposixplz/fork_newpid.c
@@ -0,0 +1,67 @@
+/* ISC license. */
+
+#include <skalibs/sysdeps.h>
+
+#ifdef SKALIBS_HASCLONENEWPID
+
+#include <skalibs/nonposix.h>
+
+#include <sys/syscall.h>
+#include <stdint.h>
+#include <unistd.h>
+#include <signal.h>
+#include <sched.h>
+#include <errno.h>
+
+#include <skalibs/uint64.h>
+
+struct clone_args
+{
+  uint64_t flags ;
+  uint64_t pidfd ;
+  uint64_t child_tid ;
+  uint64_t parent_tid ;
+  uint64_t exit_signal ;
+  uint64_t stack ;
+  uint64_t stack_size ;
+  uint64_t tls ;
+  uint64_t set_tid ;
+  uint64_t set_tid_size ;
+  uint64_t cgroup ;
+} ;
+
+pid_t fork_newpid (void)
+{
+  pid_t pid ;
+  pid_t settid = 1 ;
+  struct clone_args args =
+  {
+    .flags = CLONE_NEWPID | CLONE_PARENT_SETTID,
+    .pidfd = 0,
+    .child_tid = 0,
+    .parent_tid = (uint64_t)&pid,
+    .exit_signal = SIGCHLD,
+    .stack = 0,
+    .stack_size = 0,
+    .tls = 0,
+    .set_tid = (uint64_t)&settid,
+    .set_tid_size = 1,
+    .cgroup = 0
+  } ;
+  long r = syscall(SYS_clone3, &args, sizeof(args)) ;
+  if (r < 0) return (errno = -r, -1) ;
+  return r ? pid : 0 ;
+}
+
+#else
+
+#include <unistd.h>
+#include <errno.h>
+
+pid_t fork_newpid (void)
+{
+  errno = ENOSYS ;
+  return -1 ;
+}
+
+#endif
diff --git a/src/sysdeps/tryclonenewpid.c b/src/sysdeps/tryclonenewpid.c
new file mode 100644
index 0000000..1a1401a
--- /dev/null
+++ b/src/sysdeps/tryclonenewpid.c
@@ -0,0 +1,36 @@
+/* ISC license. */
+
+#undef _POSIX_C_SOURCE
+#undef _XOPEN_SOURCE
+
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+
+#include <sched.h>
+#include <sys/syscall.h>
+#include <stdint.h>
+#include <unistd.h>
+
+struct clone_args
+{
+  uint64_t flags ;
+  uint64_t pidfd ;
+  uint64_t child_tid ;
+  uint64_t parent_tid ;
+  uint64_t exit_signal ;
+  uint64_t stack ;
+  uint64_t stack_size ;
+  uint64_t tls ;
+  uint64_t set_tid ;
+  uint64_t set_tid_size ;
+  uint64_t cgroup ;
+} ;
+
+int main (void)
+{
+  struct clone_args args = { 0 } ;
+  args.flags = CLONE_NEWPID ;
+  syscall(SYS_clone3, &args, sizeof(struct clone_args)) ;
+  return 0 ;
+}