From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on inbox.vuxu.org X-Spam-Level: X-Spam-Status: No, score=-0.8 required=5.0 tests=DKIM_INVALID,DKIM_SIGNED, MAILING_LIST_MULTI autolearn=ham autolearn_force=no version=3.4.4 Received: (qmail 8160 invoked from network); 14 Jun 2021 19:53:49 -0000 Received: from alyss.skarnet.org (95.142.172.232) by inbox.vuxu.org with ESMTPUTF8; 14 Jun 2021 19:53:49 -0000 Received: (qmail 9767 invoked by uid 89); 14 Jun 2021 19:54:12 -0000 Mailing-List: contact supervision-help@list.skarnet.org; run by ezmlm Sender: Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: List-Id: Received: (qmail 9760 invoked from network); 14 Jun 2021 19:54:12 -0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=jlyo.org; s=varda; t=1623700424; bh=ZSdL33ON9vAFMHIzddsejQLhRY/+1CpblKT37mreP4w=; h=Received:Date:From:To:Subject:Message-ID:MIME-Version: Content-Type:Content-Disposition:Content-Transfer-Encoding; b=Lj+w1or8jmHaKX5zKziuUGJnRXWQWClOqJAERq7UekjhXOXM9btOXnW1qncsyoda/ WgnIvzgJ34hkQpx589KEMVUsHWDMta57xq+dPBEXRC43OvOnBCDiPpbKYm+ak8oBik Cr2ufrI97GcqEkB8FtUqO6KDr+gASk7ZewSgIXc8e9zWO09+R/e737Vm4RBYtCXzly f9Nkz4SNKqGuhWWroqrWPth6XlMio+wVdlyy5KlEk9vOLgAqhMvkEGt33xEDk5Bi8d 4OHHOu2nX2r+6wHB8U/CRJONn36lwSOqJWxA1XvRHoshZW8/DDw1Jy0Bs0ssVsRNFD ftluC6bbwaRrQ== Date: Mon, 14 Jun 2021 14:53:44 -0500 From: Jesse Young To: supervision@list.skarnet.org Subject: [PATCH v2] s6-supervise: Optionally run child in a new pid namespace Message-ID: <20210614195344.GA18273@varda.jlyo.net> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-Transfer-Encoding: quoted-printable Signed-off-by: Jesse Young --- Hello, This is an update on my previous patch [1], reworking it to make the delta a lot nicer. fork_newpid() uses sigjmp()/longjmp() to wrap the clone() call, giving it the same double return semantics as fork(). I'm not asking for inclusion of this into s6 as it's Linux specific. I find it useful in my environment especially when doing a s6-svc -k, which will reliably kill the process under supervision and all of its descendants. If you just need pid isolation, Linux has the hidepid=3D2 mount option for procfs, isolating processes to the same UIDs. Another way to kill an entire process subtree in Linux is to run the tree in a cgroup freezer in order to send a SIGKILL+SIGCONT to all processes in the cgroup while frozen. Freezing the processes prevents the processes themselves from fork()ing, causing a race with the killer. For lack of a good header file in s6 to put the fork_newpid(), I'm only defining it as a symbol. The pozixplz.h header in skalibs could be a candidate, but I haven't had a use for fork_newpid() outside of s6-supervise. As in the v1 patch, touching a file called "clone-newpid" in the service directory will cause s6-supervise to spawn the ./run script in a new Linux pid namespace. It's slightly related to my previous gccattr_returns_twice patch for skalibs, but that's a nice-to-have. I can update this patch when gccattr_returns_twice is released. Jesse [1] https://www.mail-archive.com/skaware@list.skarnet.org/msg01006.html package/deps.mak | 4 ++++ src/libs6/deps-lib/s6 | 1 + src/libs6/fork_newpid.c | 24 ++++++++++++++++++++++++ src/supervision/s6-supervise.c | 4 +++- 4 files changed, 32 insertions(+), 1 deletion(-) create mode 100644 src/libs6/fork_newpid.c diff --git a/package/deps.mak b/package/deps.mak index 3c051aa..a3520a9 100644 --- a/package/deps.mak +++ b/package/deps.mak @@ -40,6 +40,7 @@ src/fdholder/s6-fdholder-setdump.o src/fdholder/s6-fdhold= er-setdump.lo: src/fdho src/fdholder/s6-fdholder-store.o src/fdholder/s6-fdholder-store.lo: src/fd= holder/s6-fdholder-store.c src/include/s6/s6-fdholder.h src/fdholder/s6-fdholder-transferdump.o src/fdholder/s6-fdholder-transferd= ump.lo: src/fdholder/s6-fdholder-transferdump.c src/include/s6/s6-fdholder.h src/fdholder/s6-fdholderd.o src/fdholder/s6-fdholderd.lo: src/fdholder/s6-= fdholderd.c src/include/s6/accessrules.h src/include/s6/s6-fdholder.h +src/libs6/fork_newpid.o src/libs6/fork_newpid.lo: src/libs6/fork_newpid.c src/libs6/ftrig1_free.o src/libs6/ftrig1_free.lo: src/libs6/ftrig1_free.c = src/libs6/ftrig1.h src/libs6/ftrig1_make.o src/libs6/ftrig1_make.lo: src/libs6/ftrig1_make.c = src/libs6/ftrig1.h src/libs6/ftrigr1_zero.o src/libs6/ftrigr1_zero.lo: src/libs6/ftrigr1_zero= =2Ec src/include/s6/ftrigr.h @@ -203,11 +204,14 @@ s6-fdholder-transferdump: src/fdholder/s6-fdholder-tr= ansferdump.o ${LIBS6} s6-fdholderd: EXTRA_LIBS :=3D -lskarnet ${SOCKET_LIB} ${SYSCLOCK_LIB} s6-fdholderd: src/fdholder/s6-fdholderd.o ${LIBS6} ifeq ($(strip $(STATIC_LIBS_ARE_PIC)),) +libs6.a.xyzzy: src/libs6/fork_newpid.o libs6.a.xyzzy: src/libs6/ftrigr1_zero.o src/libs6/ftrigr_check.o src/libs6= /ftrigr_checksa.o src/libs6/ftrigr_ack.o src/libs6/ftrigr_end.o src/libs6/f= trigr_start.o src/libs6/ftrigr_startf.o src/libs6/ftrigr_subscribe.o src/li= bs6/ftrigr_unsubscribe.o src/libs6/ftrigr_update.o src/libs6/ftrigr_updateb= =2Eo src/libs6/ftrigr_wait_and.o src/libs6/ftrigr_wait_or.o src/libs6/ftrig= r_zero.o src/libs6/ftrigw_clean.o src/libs6/ftrigw_fifodir_make.o src/libs6= /ftrigw_notify.o src/libs6/ftrigw_notifyb.o src/libs6/ftrigw_notifyb_nosig.= o src/libs6/s6_accessrules_backend_cdb.o src/libs6/s6_accessrules_backend_f= s.o src/libs6/s6_accessrules_keycheck_ip4.o src/libs6/s6_accessrules_keyche= ck_ip6.o src/libs6/s6_accessrules_keycheck_reversedns.o src/libs6/s6_access= rules_keycheck_uidgid.o src/libs6/s6_accessrules_params_free.o src/libs6/s6= _accessrules_uidgid_cdb.o src/libs6/s6_accessrules_uidgid_fs.o src/libs6/s6= _compat_el_semicolon.o src/libs6/s6_dtally_pack.o src/libs6/s6_dtally_unpac= k.o src/libs6/s6_dtally_read.o src/libs6/s6_dtally_write.o src/libs6/s6_svc= _ok.o src/libs6/s6_svc_write.o src/libs6/s6_svc_writectl.o src/libs6/s6_svs= tatus_pack.o src/libs6/s6_svstatus_read.o src/libs6/s6_svstatus_unpack.o sr= c/libs6/s6_svstatus_write.o src/libs6/s6lock_acquire.o src/libs6/s6lock_che= ck.o src/libs6/s6lock_end.o src/libs6/s6lock_release.o src/libs6/s6lock_sta= rt.o src/libs6/s6lock_startf.o src/libs6/s6lock_update.o src/libs6/s6lock_w= ait_and.o src/libs6/s6lock_wait_or.o src/libs6/s6lock_zero.o src/libs6/s6_f= dholder_delete.o src/libs6/s6_fdholder_delete_async.o src/libs6/s6_fdholder= _end.o src/libs6/s6_fdholder_getdump.o src/libs6/s6_fdholder_list.o src/lib= s6/s6_fdholder_list_async.o src/libs6/s6_fdholder_list_cb.o src/libs6/s6_fd= holder_retrieve.o src/libs6/s6_fdholder_retrieve_async.o src/libs6/s6_fdhol= der_retrieve_cb.o src/libs6/s6_fdholder_setdump.o src/libs6/s6_fdholder_sta= rt.o src/libs6/s6_fdholder_store.o src/libs6/s6_fdholder_store_async.o src/= libs6/s6_supervise_link.o src/libs6/s6_supervise_unlink.o else +libs6.a.xyzzy: src/libs6/fork_newpid.lo libs6.a.xyzzy: src/libs6/ftrigr1_zero.lo src/libs6/ftrigr_check.lo src/lib= s6/ftrigr_checksa.lo src/libs6/ftrigr_ack.lo src/libs6/ftrigr_end.lo src/li= bs6/ftrigr_start.lo src/libs6/ftrigr_startf.lo src/libs6/ftrigr_subscribe.l= o src/libs6/ftrigr_unsubscribe.lo src/libs6/ftrigr_update.lo src/libs6/ftri= gr_updateb.lo src/libs6/ftrigr_wait_and.lo src/libs6/ftrigr_wait_or.lo src/= libs6/ftrigr_zero.lo src/libs6/ftrigw_clean.lo src/libs6/ftrigw_fifodir_mak= e.lo src/libs6/ftrigw_notify.lo src/libs6/ftrigw_notifyb.lo src/libs6/ftrig= w_notifyb_nosig.lo src/libs6/s6_accessrules_backend_cdb.lo src/libs6/s6_acc= essrules_backend_fs.lo src/libs6/s6_accessrules_keycheck_ip4.lo src/libs6/s= 6_accessrules_keycheck_ip6.lo src/libs6/s6_accessrules_keycheck_reversedns.= lo src/libs6/s6_accessrules_keycheck_uidgid.lo src/libs6/s6_accessrules_par= ams_free.lo src/libs6/s6_accessrules_uidgid_cdb.lo src/libs6/s6_accessrules= _uidgid_fs.lo src/libs6/s6_compat_el_semicolon.lo src/libs6/s6_dtally_pack.= lo src/libs6/s6_dtally_unpack.lo src/libs6/s6_dtally_read.lo src/libs6/s6_d= tally_write.lo src/libs6/s6_svc_ok.lo src/libs6/s6_svc_write.lo src/libs6/s= 6_svc_writectl.lo src/libs6/s6_svstatus_pack.lo src/libs6/s6_svstatus_read.= lo src/libs6/s6_svstatus_unpack.lo src/libs6/s6_svstatus_write.lo src/libs6= /s6lock_acquire.lo src/libs6/s6lock_check.lo src/libs6/s6lock_end.lo src/li= bs6/s6lock_release.lo src/libs6/s6lock_start.lo src/libs6/s6lock_startf.lo = src/libs6/s6lock_update.lo src/libs6/s6lock_wait_and.lo src/libs6/s6lock_wa= it_or.lo src/libs6/s6lock_zero.lo src/libs6/s6_fdholder_delete.lo src/libs6= /s6_fdholder_delete_async.lo src/libs6/s6_fdholder_end.lo src/libs6/s6_fdho= lder_getdump.lo src/libs6/s6_fdholder_list.lo src/libs6/s6_fdholder_list_as= ync.lo src/libs6/s6_fdholder_list_cb.lo src/libs6/s6_fdholder_retrieve.lo s= rc/libs6/s6_fdholder_retrieve_async.lo src/libs6/s6_fdholder_retrieve_cb.lo= src/libs6/s6_fdholder_setdump.lo src/libs6/s6_fdholder_start.lo src/libs6/= s6_fdholder_store.lo src/libs6/s6_fdholder_store_async.lo src/libs6/s6_supe= rvise_link.lo src/libs6/s6_supervise_unlink.lo endif libs6.so.xyzzy: EXTRA_LIBS :=3D -lskarnet +libs6.so.xyzzy: src/libs6/fork_newpid.lo libs6.so.xyzzy: src/libs6/ftrigr1_zero.lo src/libs6/ftrigr_check.lo src/li= bs6/ftrigr_checksa.lo src/libs6/ftrigr_ack.lo src/libs6/ftrigr_end.lo src/l= ibs6/ftrigr_start.lo src/libs6/ftrigr_startf.lo src/libs6/ftrigr_subscribe.= lo src/libs6/ftrigr_unsubscribe.lo src/libs6/ftrigr_update.lo src/libs6/ftr= igr_updateb.lo src/libs6/ftrigr_wait_and.lo src/libs6/ftrigr_wait_or.lo src= /libs6/ftrigr_zero.lo src/libs6/ftrigw_clean.lo src/libs6/ftrigw_fifodir_ma= ke.lo src/libs6/ftrigw_notify.lo src/libs6/ftrigw_notifyb.lo src/libs6/ftri= gw_notifyb_nosig.lo src/libs6/s6_accessrules_backend_cdb.lo src/libs6/s6_ac= cessrules_backend_fs.lo src/libs6/s6_accessrules_keycheck_ip4.lo src/libs6/= s6_accessrules_keycheck_ip6.lo src/libs6/s6_accessrules_keycheck_reversedns= =2Elo src/libs6/s6_accessrules_keycheck_uidgid.lo src/libs6/s6_accessrules_= params_free.lo src/libs6/s6_accessrules_uidgid_cdb.lo src/libs6/s6_accessru= les_uidgid_fs.lo src/libs6/s6_compat_el_semicolon.lo src/libs6/s6_dtally_pa= ck.lo src/libs6/s6_dtally_unpack.lo src/libs6/s6_dtally_read.lo src/libs6/s= 6_dtally_write.lo src/libs6/s6_svc_ok.lo src/libs6/s6_svc_write.lo src/libs= 6/s6_svc_writectl.lo src/libs6/s6_svstatus_pack.lo src/libs6/s6_svstatus_re= ad.lo src/libs6/s6_svstatus_unpack.lo src/libs6/s6_svstatus_write.lo src/li= bs6/s6lock_acquire.lo src/libs6/s6lock_check.lo src/libs6/s6lock_end.lo src= /libs6/s6lock_release.lo src/libs6/s6lock_start.lo src/libs6/s6lock_startf.= lo src/libs6/s6lock_update.lo src/libs6/s6lock_wait_and.lo src/libs6/s6lock= _wait_or.lo src/libs6/s6lock_zero.lo src/libs6/s6_fdholder_delete.lo src/li= bs6/s6_fdholder_delete_async.lo src/libs6/s6_fdholder_end.lo src/libs6/s6_f= dholder_getdump.lo src/libs6/s6_fdholder_list.lo src/libs6/s6_fdholder_list= _async.lo src/libs6/s6_fdholder_list_cb.lo src/libs6/s6_fdholder_retrieve.l= o src/libs6/s6_fdholder_retrieve_async.lo src/libs6/s6_fdholder_retrieve_cb= =2Elo src/libs6/s6_fdholder_setdump.lo src/libs6/s6_fdholder_start.lo src/l= ibs6/s6_fdholder_store.lo src/libs6/s6_fdholder_store_async.lo src/libs6/s6= _supervise_link.lo src/libs6/s6_supervise_unlink.lo ifeq ($(strip $(STATIC_LIBS_ARE_PIC)),) libs6lockd.a.xyzzy: src/libs6/s6lockd_openandlock.o diff --git a/src/libs6/deps-lib/s6 b/src/libs6/deps-lib/s6 index 45e6c33..85c70b6 100644 --- a/src/libs6/deps-lib/s6 +++ b/src/libs6/deps-lib/s6 @@ -1,3 +1,4 @@ +fork_newpid.o ftrigr1_zero.o ftrigr_check.o ftrigr_checksa.o diff --git a/src/libs6/fork_newpid.c b/src/libs6/fork_newpid.c new file mode 100644 index 0000000..457eca1 --- /dev/null +++ b/src/libs6/fork_newpid.c @@ -0,0 +1,24 @@ +#define _GNU_SOURCE + +#include +#include +#include + +static int child(void *arg) +{ + sigjmp_buf *env =3D (jmp_buf *) arg ; + siglongjmp(*env, 1) ; +} + +pid_t fork_newpid(void) +{ + sigjmp_buf env ; + if (!sigsetjmp(env, 0)) + { + pid_t ppid, cpid ; + int flags =3D CLONE_CHILD_CLEARTID | CLONE_CHILD_SETTID | CLONE_NEWPID= | SIGCHLD ; + unsigned long stack[1][128] ; + return clone(&child, &stack[1], flags, &env, &ppid, NULL, &cpid) ; + } + return 0 ; +} diff --git a/src/supervision/s6-supervise.c b/src/supervision/s6-supervise.c index bda8e52..bc55b81 100644 --- a/src/supervision/s6-supervise.c +++ b/src/supervision/s6-supervise.c @@ -37,6 +37,8 @@ # define S6_PATH_MAX 4096 #endif =20 +extern pid_t fork_newpid(void) ; + typedef enum trans_e trans_t, *trans_t_ref ; enum trans_e { @@ -253,7 +255,7 @@ static void trystart (void) fd_close(p[1]) ; fd_close(p[0]) ; return ; } - pid =3D fork() ; + pid =3D access("clone-newpid", R_OK) ? fork() : fork_newpid() ; if (pid < 0) { settimeout(60) ; --=20 2.32.0