svn commit: r333162 - in stable/11: lib/libc/sys sys/compat/freebsd32 sys/kern sys/sys tests/sys/kern
Konstantin Belousov
kib at FreeBSD.org
Wed May 2 07:57:38 UTC 2018
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);
More information about the svn-src-stable
mailing list