summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLaurent Bercot <ska-skaware@skarnet.org>2023-09-08 04:06:34 +0000
committerLaurent Bercot <ska@appnovation.com>2023-09-08 04:06:34 +0000
commit15ebb5b8add8ee6a304981dd604fae78f491b34c (patch)
treeead3340839fdd15066ce95f51235e21740a07d8f /src
parent1cbe4b09e027e31d258c24feee0be46958888b93 (diff)
downloads6-15ebb5b8add8ee6a304981dd604fae78f491b34c.tar.xz
Add ucspiserver.h, support posix_spawn() in s6-ipcserverd
Signed-off-by: Laurent Bercot <ska@appnovation.com>
Diffstat (limited to 'src')
-rw-r--r--src/conn-tools/deps-exe/s6-ipcserverd1
-rw-r--r--src/conn-tools/s6-ipcserverd.c74
-rw-r--r--src/include/s6/s6.h1
-rw-r--r--src/include/s6/ucspiserver.h10
-rw-r--r--src/libs6/deps-lib/s61
-rw-r--r--src/libs6/s6_ucspiserver_spawn.c116
6 files changed, 162 insertions, 41 deletions
diff --git a/src/conn-tools/deps-exe/s6-ipcserverd b/src/conn-tools/deps-exe/s6-ipcserverd
index 19869b2..bfcb622 100644
--- a/src/conn-tools/deps-exe/s6-ipcserverd
+++ b/src/conn-tools/deps-exe/s6-ipcserverd
@@ -1,2 +1,3 @@
+${LIBS6}
-lskarnet
${SOCKET_LIB}
diff --git a/src/conn-tools/s6-ipcserverd.c b/src/conn-tools/s6-ipcserverd.c
index 3de8fae..35afdc5 100644
--- a/src/conn-tools/s6-ipcserverd.c
+++ b/src/conn-tools/s6-ipcserverd.c
@@ -22,9 +22,11 @@
#include <skalibs/socket.h>
#include <skalibs/exec.h>
+#include <s6/ucspiserver.h>
+
#define USAGE "s6-ipcserverd [ -v verbosity ] [ -1 ] [ -P | -p ] [ -c maxconn ] [ -C localmaxconn ] prog..."
-#define ABSOLUTE_MAXCONN 1000
+#define ABSOLUTE_MAXCONN 16384
static unsigned int maxconn = 40 ;
static unsigned int localmaxconn = 40 ;
@@ -228,43 +230,16 @@ static inline void handle_signals (void)
/* New connection handling */
-static void run_child (int, uid_t, gid_t, unsigned int, char const *, char const *const *) gccattr_noreturn ;
-static void run_child (int s, uid_t uid, gid_t gid, unsigned int num, char const *remotepath, char const *const *argv)
-{
- size_t rplen = strlen(remotepath) + 1 ;
- unsigned int n = 0 ;
- char fmt[65 + UID_FMT + GID_FMT + UINT_FMT + rplen] ;
- PROG = "s6-ipcserver (child)" ;
- if ((fd_move(1, s) < 0) || (fd_copy(0, 1) < 0))
- strerr_diefu1sys(111, "move fds") ;
- memcpy(fmt+n, "PROTO=IPC\0IPCREMOTEEUID", 23) ; n += 23 ;
- if (flaglookup)
- {
- fmt[n++] = '=' ;
- n += uid_fmt(fmt+n, uid) ;
- }
- fmt[n++] = 0 ;
- memcpy(fmt+n, "IPCREMOTEEGID", 13) ; n += 13 ;
- if (flaglookup)
- {
- fmt[n++] = '=' ;
- n += gid_fmt(fmt+n, gid) ;
- }
- fmt[n++] = 0 ;
- memcpy(fmt+n, "IPCCONNNUM=", 11) ; n += 11 ;
- if (flaglookup) n += uint_fmt(fmt+n, num) ;
- fmt[n++] = 0 ;
- memcpy(fmt+n, "IPCREMOTEPATH=", 14) ; n += 14 ;
- memcpy(fmt+n, remotepath, rplen) ; n += rplen ;
- xmexec_n(argv, fmt, n, 5) ;
-}
-
-static void new_connection (int s, char const *remotepath, char const *const *argv)
+static void new_connection (int s, char const *remotepath, char const *const *argv, char const *const *envp, size_t envlen)
{
uid_t uid = 0 ;
gid_t gid = 0 ;
+ size_t m = 0 ;
+ size_t rplen = strlen(remotepath) + 1 ;
pid_t pid ;
unsigned int num, i ;
+ char fmt[65 + UID_FMT + GID_FMT + UINT_FMT + rplen] ;
+
if (flaglookup && (getpeereid(s, &uid, &gid) < 0))
{
if (verbosity) strerr_warnwu1sys("getpeereid") ;
@@ -277,16 +252,32 @@ static void new_connection (int s, char const *remotepath, char const *const *ar
log_deny(uid, gid, num) ;
return ;
}
- pid = fork() ;
- if (pid < 0)
+
+ memcpy(fmt + m, "PROTO=IPC\0IPCREMOTEEUID", 23) ; m += 23 ;
+ if (flaglookup)
{
- if (verbosity) strerr_warnwu1sys("fork") ;
- return ;
+ fmt[m++] = '=' ;
+ m += uid_fmt(fmt + m, uid) ;
+ }
+ fmt[m++] = 0 ;
+ memcpy(fmt + m, "IPCREMOTEEGID", 13) ; m += 13 ;
+ if (flaglookup)
+ {
+ fmt[m++] = '=' ;
+ m += gid_fmt(fmt + m, gid) ;
}
- else if (!pid)
+ fmt[m++] = 0 ;
+ memcpy(fmt + m, "IPCCONNNUM=", 11) ; m += 11 ;
+ if (flaglookup) m += uint_fmt(fmt + m, num) ;
+ fmt[m++] = 0 ;
+ memcpy(fmt + m, "IPCREMOTEPATH=", 14) ; m += 14 ;
+ memcpy(fmt + m, remotepath, rplen) ; m += rplen ;
+
+ pid = s6_ucspiserver_spawn(s, argv, envp, envlen, fmt, m, 5) ;
+ if (!pid)
{
- selfpipe_finish() ;
- run_child(s, uid, gid, num+1, remotepath, argv) ;
+ if (verbosity) strerr_warnwu1sys("fork") ;
+ return ;
}
if (i < uidlen) uidnum[i].right = num + 1 ;
@@ -376,6 +367,7 @@ int main (int argc, char const *const *argv)
{
piduid_t inyostack0[maxconn] ;
uidnum_t inyostack1[flaglookup ? maxconn : 1] ;
+ size_t envlen = env_len((char const *const *)environ) ;
piduid = inyostack0 ;
uidnum = inyostack1 ;
@@ -400,7 +392,7 @@ int main (int argc, char const *const *argv)
}
else
{
- new_connection(sock, remotepath, argv) ;
+ new_connection(sock, remotepath, argv, (char const *const *)environ, envlen) ;
fd_close(sock) ;
}
}
diff --git a/src/include/s6/s6.h b/src/include/s6/s6.h
index ef521bb..31b8e00 100644
--- a/src/include/s6/s6.h
+++ b/src/include/s6/s6.h
@@ -10,5 +10,6 @@
#include <s6/accessrules.h>
#include <s6/lock.h>
#include <s6/auto.h>
+#include <s6/ucspiserver.h>
#endif
diff --git a/src/include/s6/ucspiserver.h b/src/include/s6/ucspiserver.h
new file mode 100644
index 0000000..7ae03c2
--- /dev/null
+++ b/src/include/s6/ucspiserver.h
@@ -0,0 +1,10 @@
+/* ISC license. */
+
+#ifndef S6_SERVER_H
+#define S6_SERVER_H
+
+#include <sys/types.h>
+
+extern pid_t s6_ucspiserver_spawn (int, char const *const *, char const *const *, size_t, char const *, size_t, size_t) ;
+
+#endif
diff --git a/src/libs6/deps-lib/s6 b/src/libs6/deps-lib/s6
index 9924d83..13b9a83 100644
--- a/src/libs6/deps-lib/s6
+++ b/src/libs6/deps-lib/s6
@@ -70,4 +70,5 @@ s6_supervise_link.o
s6_supervise_link_names.o
s6_supervise_unlink.o
s6_supervise_unlink_names.o
+s6_ucspiserver_spawn.o
-lskarnet
diff --git a/src/libs6/s6_ucspiserver_spawn.c b/src/libs6/s6_ucspiserver_spawn.c
new file mode 100644
index 0000000..982d754
--- /dev/null
+++ b/src/libs6/s6_ucspiserver_spawn.c
@@ -0,0 +1,116 @@
+/* ISC license. */
+
+#include <skalibs/sysdeps.h>
+
+#include <stdint.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <skalibs/uint16.h>
+#include <skalibs/fmtscan.h>
+#include <skalibs/djbunix.h>
+
+#include <s6/ucspiserver.h>
+
+#ifdef SKALIBS_HASPOSIXSPAWN
+
+#include <errno.h>
+#include <signal.h>
+#include <stdlib.h>
+#include <spawn.h>
+
+#include <skalibs/config.h>
+#include <skalibs/env.h>
+
+#ifdef SKALIBS_HASPOSIXSPAWNEARLYRETURN
+extern pid_t child_spawn_workaround (pid_t, int const *) ; /* XXX: non-public skalibs function */
+#endif
+
+pid_t s6_ucspiserver_spawn (int fd, char const *const *argv, char const *const *envp, size_t envlen, char const *modifs, size_t modiflen, size_t modifn)
+{
+ pid_t pid ;
+ posix_spawn_file_actions_t actions ;
+ posix_spawnattr_t attr ;
+ sigset_t set ;
+ int e ;
+ int nopath = !getenv("PATH") ;
+#ifdef SKALIBS_HASPOSIXSPAWNEARLYRETURN
+ int p[2] ;
+#endif
+ char const *newenvp[envlen + modifn + 1] ;
+
+#ifdef SKALIBS_HASPOSIXSPAWNEARLYRETURN
+ if (pipecoe(p) == -1) return 0 ;
+#endif
+ e = posix_spawnattr_init(&attr) ;
+ if (e) goto err ;
+ sigemptyset(&set) ;
+ e = posix_spawnattr_setsigmask(&attr, &set) ;
+ if (e) goto errattr ;
+ e = posix_spawnattr_setflags(&attr, POSIX_SPAWN_SETSIGMASK) ;
+ if (e) goto errattr ;
+ e = posix_spawn_file_actions_init(&actions) ;
+ if (e) goto errattr ;
+ e = posix_spawn_file_actions_adddup2(&actions, fd, 0) ;
+ if (e) goto erractions ;
+ e = posix_spawn_file_actions_adddup2(&actions, fd, 1) ;
+ if (e) goto erractions ;
+ if (fd > 1)
+ {
+ e = posix_spawn_file_actions_addclose(&actions, fd) ;
+ if (e) goto erractions ;
+ }
+
+ env_mergen(newenvp, envlen + modifn + 1, envp, envlen, modifs, modiflen, modifn) ;
+ if (nopath && (setenv("PATH", SKALIBS_DEFAULTPATH, 0) < 0)) { e = errno ; goto erractions ; }
+ e = posix_spawnp(&pid, argv[0], &actions, &attr, (char *const *)argv, (char *const *)newenvp) ;
+ if (nopath) unsetenv("PATH") ;
+ if (e) goto erractions ;
+
+ posix_spawn_file_actions_destroy(&actions) ;
+ posix_spawnattr_destroy(&attr) ;
+#ifdef SKALIBS_HASPOSIXSPAWNEARLYRETURN
+ return child_spawn_workaround(pid, p) ;
+#else
+ return pid ;
+#endif
+
+ erractions:
+ posix_spawn_file_actions_destroy(&actions) ;
+ errattr:
+ posix_spawnattr_destroy(&attr) ;
+ err:
+#ifdef SKALIBS_HASPOSIXSPAWNEARLYRETURN
+ fd_close(p[1]) ;
+ fd_close(p[0]) ;
+#endif
+ errno = e ;
+ return 0 ;
+}
+
+#else
+
+#include <skalibs/strerr.h>
+#include <skalibs/selfpipe.h>
+#include <skalibs/exec.h>
+
+pid_t s6_ucspiserver_spawn (int fd, char const *const *argv, char const *const *envp, size_t envlen, char const *modifs, size_t modiflen, size_t modifn)
+{
+ pid_t pid = fork() ;
+ if (pid == -1) return 0 ;
+ if (!pid)
+ {
+ size_t proglen = strlen(PROG) ;
+ char newprog[proglen + 9] ;
+ memcpy(newprog, PROG, proglen) ;
+ memcpy(newprog, " (child)", 9) ;
+ PROG = newprog ;
+ if ((fd_move(1, fd) == -1) || (fd_copy(0, 1) == -1))
+ strerr_diefu1sys(111, "move fds") ;
+ selfpipe_finish() ;
+ xmexec_fn(argv, envp, envlen, modifs, modiflen, modifn) ;
+ }
+ return pid ;
+}
+
+#endif