From owner-svn-src-all@freebsd.org Wed May 2 07:57:38 2018 Return-Path: Delivered-To: svn-src-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 2FAB9FC53E2; Wed, 2 May 2018 07:57:38 +0000 (UTC) (envelope-from kib@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id BA0986ED1F; Wed, 2 May 2018 07:57:37 +0000 (UTC) (envelope-from kib@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 91F8763B6; Wed, 2 May 2018 07:57:37 +0000 (UTC) (envelope-from kib@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id w427vbKf080388; Wed, 2 May 2018 07:57:37 GMT (envelope-from kib@FreeBSD.org) Received: (from kib@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id w427vaQd080376; Wed, 2 May 2018 07:57:36 GMT (envelope-from kib@FreeBSD.org) Message-Id: <201805020757.w427vaQd080376@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: kib set sender to kib@FreeBSD.org using -f From: Konstantin Belousov Date: Wed, 2 May 2018 07:57:36 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-11@freebsd.org Subject: svn commit: r333162 - in stable/11: lib/libc/sys sys/compat/freebsd32 sys/kern sys/sys tests/sys/kern X-SVN-Group: stable-11 X-SVN-Commit-Author: kib X-SVN-Commit-Paths: in stable/11: lib/libc/sys sys/compat/freebsd32 sys/kern sys/sys tests/sys/kern X-SVN-Commit-Revision: 333162 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.25 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 02 May 2018 07:57:38 -0000 Author: kib Date: Wed May 2 07:57:36 2018 New Revision: 333162 URL: https://svnweb.freebsd.org/changeset/base/333162 Log: MFC r332740: Add PROC_PDEATHSIG_SET to procctl interface. MFC r332825: Rename PROC_PDEATHSIG_SET -> PROC_PDEATHSIG_CTL. MFC r333067: Remove redundant pipe from pdeathsig.c test. Added: stable/11/tests/sys/kern/pdeathsig.c - copied, changed from r332740, head/tests/sys/kern/pdeathsig.c stable/11/tests/sys/kern/pdeathsig_helper.c - copied, changed from r332740, head/tests/sys/kern/pdeathsig_helper.c Modified: stable/11/lib/libc/sys/procctl.2 stable/11/sys/compat/freebsd32/freebsd32_misc.c stable/11/sys/kern/kern_exec.c stable/11/sys/kern/kern_exit.c stable/11/sys/kern/kern_fork.c stable/11/sys/kern/kern_procctl.c stable/11/sys/sys/proc.h stable/11/sys/sys/procctl.h stable/11/tests/sys/kern/Makefile Directory Properties: stable/11/ (props changed) Modified: stable/11/lib/libc/sys/procctl.2 ============================================================================== --- stable/11/lib/libc/sys/procctl.2 Wed May 2 07:42:47 2018 (r333161) +++ stable/11/lib/libc/sys/procctl.2 Wed May 2 07:57:36 2018 (r333162) @@ -29,7 +29,7 @@ .\" .\" $FreeBSD$ .\" -.Dd November 21, 2017 +.Dd April 20, 2018 .Dt PROCCTL 2 .Os .Sh NAME @@ -391,6 +391,37 @@ otherwise. See the note about sysctl .Dv kern.trap_enocap above, which gives independent global control of signal delivery. +.It Dv PROC_PDEATHSIG_CTL +Request the delivery of a signal when the parent of the calling +process exits. +.Fa idtype +must be +.Dv P_PID +and +.Fa id +must be the either caller's pid or zero, with no difference in effect. +The value is cleared for child processes +and when executing set-user-ID or set-group-ID binaries. +.Fa arg +must point to a value of type +.Vt int +indicating the signal +that should be delivered to the caller. +Use zero to cancel a previously requested signal delivery. +.It Dv PROC_PDEATHSIG_STATUS +Query the current signal number that will be delivered when the parent +of the calling process exits. +.Fa idtype +must be +.Dv P_PID +and +.Fa id +must be the either caller's pid or zero, with no difference in effect. +.Fa arg +must point to a memory location that can hold a value of type +.Vt int . +If signal delivery has not been requested, it will contain zero +on return. .El .Sh NOTES Disabling tracing on a process should not be considered a security @@ -487,6 +518,15 @@ parameter for the or .Dv PROC_TRAPCAP_CTL request is invalid. +.It Bq Er EINVAL +The +.Dv PROC_PDEATHSIG_CTL +or +.Dv PROC_PDEATHSIG_STATUS +request referenced an unsupported +.Fa id , +.Fa idtype +or invalid signal number. .El .Sh SEE ALSO .Xr dtrace 1 , @@ -506,3 +546,8 @@ function appeared in The reaper facility is based on a similar feature of Linux and DragonflyBSD, and first appeared in .Fx 10.2 . +The +.Dv PROC_PDEATHSIG_CTL +facility is based on the prctl(PR_SET_PDEATHSIG, ...) feature of Linux, +and first appeared in +.Fx 12.0 . Modified: stable/11/sys/compat/freebsd32/freebsd32_misc.c ============================================================================== --- stable/11/sys/compat/freebsd32/freebsd32_misc.c Wed May 2 07:42:47 2018 (r333161) +++ stable/11/sys/compat/freebsd32/freebsd32_misc.c Wed May 2 07:57:36 2018 (r333162) @@ -3057,7 +3057,7 @@ freebsd32_procctl(struct thread *td, struct freebsd32_ union { struct procctl_reaper_pids32 rp; } x32; - int error, error1, flags; + int error, error1, flags, signum; switch (uap->com) { case PROC_SPROTECT: @@ -3095,6 +3095,15 @@ freebsd32_procctl(struct thread *td, struct freebsd32_ case PROC_TRAPCAP_STATUS: data = &flags; break; + case PROC_PDEATHSIG_CTL: + error = copyin(uap->data, &signum, sizeof(signum)); + if (error != 0) + return (error); + data = &signum; + break; + case PROC_PDEATHSIG_STATUS: + data = &signum; + break; default: return (EINVAL); } @@ -3114,6 +3123,10 @@ freebsd32_procctl(struct thread *td, struct freebsd32_ case PROC_TRAPCAP_STATUS: if (error == 0) error = copyout(&flags, uap->data, sizeof(flags)); + break; + case PROC_PDEATHSIG_STATUS: + if (error == 0) + error = copyout(&signum, uap->data, sizeof(signum)); break; } return (error); Modified: stable/11/sys/kern/kern_exec.c ============================================================================== --- stable/11/sys/kern/kern_exec.c Wed May 2 07:42:47 2018 (r333161) +++ stable/11/sys/kern/kern_exec.c Wed May 2 07:57:36 2018 (r333162) @@ -520,6 +520,10 @@ interpret: credential_changing |= will_transition; #endif + /* Don't inherit PROC_PDEATHSIG_CTL value if setuid/setgid. */ + if (credential_changing) + imgp->proc->p_pdeathsig = 0; + if (credential_changing && #ifdef CAPABILITY_MODE ((oldcred->cr_flags & CRED_FLAG_CAPMODE) == 0) && Modified: stable/11/sys/kern/kern_exit.c ============================================================================== --- stable/11/sys/kern/kern_exit.c Wed May 2 07:42:47 2018 (r333161) +++ stable/11/sys/kern/kern_exit.c Wed May 2 07:57:36 2018 (r333162) @@ -479,6 +479,12 @@ exit1(struct thread *td, int rval, int signo) PROC_LOCK(q->p_reaper); pksignal(q->p_reaper, SIGCHLD, ksi1); PROC_UNLOCK(q->p_reaper); + } else if (q->p_pdeathsig > 0) { + /* + * The child asked to received a signal + * when we exit. + */ + kern_psignal(q, q->p_pdeathsig); } } else { /* @@ -519,6 +525,13 @@ exit1(struct thread *td, int rval, int signo) */ while ((q = LIST_FIRST(&p->p_orphans)) != NULL) { PROC_LOCK(q); + /* + * If we are the real parent of this process + * but it has been reparented to a debugger, then + * check if it asked for a signal when we exit. + */ + if (q->p_pdeathsig > 0) + kern_psignal(q, q->p_pdeathsig); CTR2(KTR_PTRACE, "exit: pid %d, clearing orphan %d", p->p_pid, q->p_pid); clear_orphan(q); Modified: stable/11/sys/kern/kern_fork.c ============================================================================== --- stable/11/sys/kern/kern_fork.c Wed May 2 07:42:47 2018 (r333161) +++ stable/11/sys/kern/kern_fork.c Wed May 2 07:57:36 2018 (r333162) @@ -425,6 +425,7 @@ do_fork(struct thread *td, struct fork_req *fr, struct bzero(&p2->p_startzero, __rangeof(struct proc, p_startzero, p_endzero)); p2->p_ptevents = 0; + p2->p_pdeathsig = 0; /* Tell the prison that we exist. */ prison_proc_hold(p2->p_ucred->cr_prison); Modified: stable/11/sys/kern/kern_procctl.c ============================================================================== --- stable/11/sys/kern/kern_procctl.c Wed May 2 07:42:47 2018 (r333161) +++ stable/11/sys/kern/kern_procctl.c Wed May 2 07:57:36 2018 (r333162) @@ -431,7 +431,7 @@ sys_procctl(struct thread *td, struct procctl_args *ua struct procctl_reaper_pids rp; struct procctl_reaper_kill rk; } x; - int error, error1, flags; + int error, error1, flags, signum; switch (uap->com) { case PROC_SPROTECT: @@ -467,6 +467,15 @@ sys_procctl(struct thread *td, struct procctl_args *ua case PROC_TRAPCAP_STATUS: data = &flags; break; + case PROC_PDEATHSIG_CTL: + error = copyin(uap->data, &signum, sizeof(signum)); + if (error != 0) + return (error); + data = &signum; + break; + case PROC_PDEATHSIG_STATUS: + data = &signum; + break; default: return (EINVAL); } @@ -486,6 +495,10 @@ sys_procctl(struct thread *td, struct procctl_args *ua if (error == 0) error = copyout(&flags, uap->data, sizeof(flags)); break; + case PROC_PDEATHSIG_STATUS: + if (error == 0) + error = copyout(&signum, uap->data, sizeof(signum)); + break; } return (error); } @@ -527,6 +540,7 @@ kern_procctl(struct thread *td, idtype_t idtype, id_t struct pgrp *pg; struct proc *p; int error, first_error, ok; + int signum; bool tree_locked; switch (com) { @@ -537,8 +551,31 @@ kern_procctl(struct thread *td, idtype_t idtype, id_t case PROC_REAP_KILL: case PROC_TRACE_STATUS: case PROC_TRAPCAP_STATUS: + case PROC_PDEATHSIG_CTL: + case PROC_PDEATHSIG_STATUS: if (idtype != P_PID) return (EINVAL); + } + + switch (com) { + case PROC_PDEATHSIG_CTL: + signum = *(int *)data; + p = td->td_proc; + if ((id != 0 && id != p->p_pid) || + (signum != 0 && !_SIG_VALID(signum))) + return (EINVAL); + PROC_LOCK(p); + p->p_pdeathsig = signum; + PROC_UNLOCK(p); + return (0); + case PROC_PDEATHSIG_STATUS: + p = td->td_proc; + if (id != 0 && id != p->p_pid) + return (EINVAL); + PROC_LOCK(p); + *(int *)data = p->p_pdeathsig; + PROC_UNLOCK(p); + return (0); } switch (com) { Modified: stable/11/sys/sys/proc.h ============================================================================== --- stable/11/sys/sys/proc.h Wed May 2 07:42:47 2018 (r333161) +++ stable/11/sys/sys/proc.h Wed May 2 07:57:36 2018 (r333162) @@ -674,6 +674,7 @@ struct proc { uint64_t p_elf_flags; /* (x) ELF flags */ sigqueue_t p_sigqueue; /* (c) Sigs not delivered to a td. */ #define p_siglist p_sigqueue.sq_signals + int p_pdeathsig; /* (c) Signal from parent on exit. */ }; #define p_session p_pgrp->pg_session Modified: stable/11/sys/sys/procctl.h ============================================================================== --- stable/11/sys/sys/procctl.h Wed May 2 07:42:47 2018 (r333161) +++ stable/11/sys/sys/procctl.h Wed May 2 07:57:36 2018 (r333162) @@ -49,6 +49,8 @@ #define PROC_TRACE_STATUS 8 /* query tracing status */ #define PROC_TRAPCAP_CTL 9 /* trap capability errors */ #define PROC_TRAPCAP_STATUS 10 /* query trap capability status */ +#define PROC_PDEATHSIG_CTL 11 /* set parent death signal */ +#define PROC_PDEATHSIG_STATUS 12 /* get parent death signal */ /* Operations for PROC_SPROTECT (passed in integer arg). */ #define PPROT_OP(x) ((x) & 0xf) Modified: stable/11/tests/sys/kern/Makefile ============================================================================== --- stable/11/tests/sys/kern/Makefile Wed May 2 07:42:47 2018 (r333161) +++ stable/11/tests/sys/kern/Makefile Wed May 2 07:57:36 2018 (r333162) @@ -15,6 +15,9 @@ ATF_TESTS_C+= unix_seqpacket_test ATF_TESTS_C+= unix_passfd_test TEST_METADATA.unix_seqpacket_test+= timeout="15" ATF_TESTS_C+= waitpid_nohang +ATF_TESTS_C+= pdeathsig + +PROGS+= pdeathsig_helper LIBADD.ptrace_test+= pthread LIBADD.unix_seqpacket_test+= pthread Copied and modified: stable/11/tests/sys/kern/pdeathsig.c (from r332740, head/tests/sys/kern/pdeathsig.c) ============================================================================== --- head/tests/sys/kern/pdeathsig.c Wed Apr 18 21:31:13 2018 (r332740, copy source) +++ stable/11/tests/sys/kern/pdeathsig.c Wed May 2 07:57:36 2018 (r333162) @@ -53,42 +53,42 @@ ATF_TC_BODY(arg_validation, tc) /* bad signal */ signum = 8888; - rc = procctl(P_PID, 0, PROC_PDEATHSIG_SET, &signum); + rc = procctl(P_PID, 0, PROC_PDEATHSIG_CTL, &signum); ATF_CHECK_EQ(-1, rc); ATF_CHECK_EQ(EINVAL, errno); /* bad id type */ signum = SIGINFO; - rc = procctl(8888, 0, PROC_PDEATHSIG_SET, &signum); + rc = procctl(8888, 0, PROC_PDEATHSIG_CTL, &signum); ATF_CHECK_EQ(-1, rc); ATF_CHECK_EQ(EINVAL, errno); /* bad id (pid that doesn't match mine or zero) */ signum = SIGINFO; rc = procctl(P_PID, (((getpid() + 1) % 10) + 100), - PROC_PDEATHSIG_SET, &signum); + PROC_PDEATHSIG_CTL, &signum); ATF_CHECK_EQ(-1, rc); ATF_CHECK_EQ(EINVAL, errno); /* null pointer */ signum = SIGINFO; - rc = procctl(P_PID, 0, PROC_PDEATHSIG_SET, NULL); + rc = procctl(P_PID, 0, PROC_PDEATHSIG_CTL, NULL); ATF_CHECK_EQ(-1, rc); ATF_CHECK_EQ(EFAULT, errno); /* good (pid == 0) */ signum = SIGINFO; - rc = procctl(P_PID, 0, PROC_PDEATHSIG_SET, &signum); + rc = procctl(P_PID, 0, PROC_PDEATHSIG_CTL, &signum); ATF_CHECK_EQ(0, rc); /* good (pid == my pid) */ signum = SIGINFO; - rc = procctl(P_PID, getpid(), PROC_PDEATHSIG_SET, &signum); + rc = procctl(P_PID, getpid(), PROC_PDEATHSIG_CTL, &signum); ATF_CHECK_EQ(0, rc); /* check that we can read the signal number back */ signum = 0xdeadbeef; - rc = procctl(P_PID, 0, PROC_PDEATHSIG_GET, &signum); + rc = procctl(P_PID, 0, PROC_PDEATHSIG_STATUS, &signum); ATF_CHECK_EQ(0, rc); ATF_CHECK_EQ(SIGINFO, signum); } @@ -102,14 +102,14 @@ ATF_TC_BODY(fork_no_inherit, tc) /* request a signal on parent death in the parent */ signum = SIGINFO; - rc = procctl(P_PID, 0, PROC_PDEATHSIG_SET, &signum); + rc = procctl(P_PID, 0, PROC_PDEATHSIG_CTL, &signum); rc = fork(); ATF_REQUIRE(rc != -1); if (rc == 0) { /* check that we didn't inherit the setting */ signum = 0xdeadbeef; - rc = procctl(P_PID, 0, PROC_PDEATHSIG_GET, &signum); + rc = procctl(P_PID, 0, PROC_PDEATHSIG_STATUS, &signum); assert(rc == 0); assert(signum == 0); _exit(0); @@ -138,7 +138,7 @@ ATF_TC_BODY(exec_inherit, tc) /* request a signal on parent death and register a handler */ signum = SIGINFO; - rc = procctl(P_PID, 0, PROC_PDEATHSIG_SET, &signum); + rc = procctl(P_PID, 0, PROC_PDEATHSIG_CTL, &signum); assert(rc == 0); /* execute helper program: it asserts that it has the setting */ @@ -186,7 +186,7 @@ ATF_TC_BODY(signal_delivered, tc) signal(signum, dummy_signal_handler); /* request a signal on death of our parent B */ - rc = procctl(P_PID, 0, PROC_PDEATHSIG_SET, &signum); + rc = procctl(P_PID, 0, PROC_PDEATHSIG_CTL, &signum); assert(rc == 0); /* tell B that we're ready for it to exit now */ @@ -229,7 +229,6 @@ ATF_TC_BODY(signal_delivered_ptrace, tc) int rc; int pipe_ca[2]; int pipe_db[2]; - int pipe_cd[2]; char buffer; int status; @@ -237,8 +236,6 @@ ATF_TC_BODY(signal_delivered_ptrace, tc) ATF_REQUIRE(rc == 0); rc = pipe(pipe_db); ATF_REQUIRE(rc == 0); - rc = pipe(pipe_cd); - ATF_REQUIRE(rc == 0); rc = fork(); ATF_REQUIRE(rc != -1); @@ -263,12 +260,8 @@ ATF_TC_BODY(signal_delivered_ptrace, tc) signal(signum, dummy_signal_handler); /* request a signal on parent death and register a handler */ - rc = procctl(P_PID, 0, PROC_PDEATHSIG_SET, &signum); + rc = procctl(P_PID, 0, PROC_PDEATHSIG_CTL, &signum); assert(rc == 0); - - /* tell D we are ready for it to attach */ - rc = write(pipe_cd[1], ".", 1); - assert(rc == 1); /* wait for B to die and signal us... */ signum = 0xdeadbeef; Copied and modified: stable/11/tests/sys/kern/pdeathsig_helper.c (from r332740, head/tests/sys/kern/pdeathsig_helper.c) ============================================================================== --- head/tests/sys/kern/pdeathsig_helper.c Wed Apr 18 21:31:13 2018 (r332740, copy source) +++ stable/11/tests/sys/kern/pdeathsig_helper.c Wed May 2 07:57:36 2018 (r333162) @@ -38,11 +38,11 @@ int main(int argc, char **argv) /* * This program is executed by the pdeathsig test - * to check if the PROC_PDEATHSIG_SET setting was + * to check if the PROC_PDEATHSIG_CTL setting was * inherited. */ signum = 0xdeadbeef; - rc = procctl(P_PID, 0, PROC_PDEATHSIG_GET, &signum); + rc = procctl(P_PID, 0, PROC_PDEATHSIG_STATUS, &signum); assert(rc == 0); assert(signum == SIGINFO);