diff options
author | Laurent Bercot <ska-skaware@skarnet.org> | 2017-03-22 21:37:30 +0000 |
---|---|---|
committer | Laurent Bercot <ska-skaware@skarnet.org> | 2017-03-22 21:37:30 +0000 |
commit | dddbfab568d42e443f102d35c84432824cc59fee (patch) | |
tree | 4983b1f5b44f861a3abc60ba7d47476820fcbb2f /src/sbearssl/sbearssl_prep_spawn_drop.c | |
parent | 6278e21405c40df65f8de6a9799576d1eb346164 (diff) | |
download | s6-networking-dddbfab568d42e443f102d35c84432824cc59fee.tar.xz |
Fix case where s6-tls[cd] would sometimes not detect an application and remain there forever with its zombie, both condemned to err in limbo for all eternity, the living and the dead, hand in hand
Diffstat (limited to 'src/sbearssl/sbearssl_prep_spawn_drop.c')
-rw-r--r-- | src/sbearssl/sbearssl_prep_spawn_drop.c | 35 |
1 files changed, 35 insertions, 0 deletions
diff --git a/src/sbearssl/sbearssl_prep_spawn_drop.c b/src/sbearssl/sbearssl_prep_spawn_drop.c new file mode 100644 index 0000000..1ca7eb8 --- /dev/null +++ b/src/sbearssl/sbearssl_prep_spawn_drop.c @@ -0,0 +1,35 @@ +/* ISC license. */ + +#include <unistd.h> +#include <signal.h> +#include <skalibs/env.h> +#include <skalibs/strerr2.h> +#include <skalibs/djbunix.h> +#include <skalibs/selfpipe.h> +#include "sbearssl-internal.h" + +pid_t sbearssl_prep_spawn_drop (char const *const *argv, char const *const *envp, int *fds, uid_t uid, gid_t gid, uint32_t options) +{ + pid_t pid ; + + fds[4] = selfpipe_init() ; + if (fds[4] < 0) strerr_diefu1sys(111, "init selfpipe") ; + if (selfpipe_trap(SIGCHLD) < 0) strerr_diefu1sys(111, "trap SIGCHLD") ; + + if (!(options & 1)) pid = child_spawn2(argv[0], argv, envp, fds) ; + else + { + char const modifs[] = "CADIR\0CAFILE\0KEYFILE\0CERTFILE\0TLS_UID\0TLS_GID" ; + size_t modiflen = sizeof(modifs) ; + size_t n = env_len(envp) ; + char const *newenv[n + 7] ; + size_t newenvlen = env_merge(newenv, n+7, envp, n, modifs, modiflen) ; + if (!newenvlen) return 0 ; + pid = child_spawn2(argv[0], argv, newenv, fds) ; + } + + if (!pid) strerr_diefu2sys(111, "spawn ", argv[0]) ; + if (gid && setgid(gid) < 0) strerr_diefu1sys(111, "setgid") ; + if (uid && setuid(uid) < 0) strerr_diefu1sys(111, "setuid") ; + return pid ; +} |