Index: lib/libc/sys/procctl.2 =================================================================== --- lib/libc/sys/procctl.2 +++ lib/libc/sys/procctl.2 @@ -29,7 +29,7 @@ .\" .\" $FreeBSD$ .\" -.Dd August 31, 2019 +.Dd October 4, 2019 .Dt PROCCTL 2 .Os .Sh NAME @@ -71,7 +71,7 @@ .Fa cmd argument. The following commands are supported: -.Bl -tag -width PROC_TRAPCAP_STATUS +.Bl -tag -width PROC_LOGSIGEXIT_STATUS .It Dv PROC_ASLR_CTL Controls the Address Space Layout Randomization (ASLR) in the program images created @@ -112,6 +112,39 @@ the .Dv PROC_ASLR_ACTIVE flag is or-ed with the value listed above. +.It Dv PROC_LOGSIGEXIT_CTL +Controls the logging of exits due to signals that would normally cause a core +dump. +The +.Va arg +parameter must point to an integer variable holding one of the following values: +.Bl -tag -width PROC_LOGSIGEXIT_FORCE_DISABLE +.It Dv PROC_LOGSIGEXIT_FORCE_ENABLE +Enables logging of exits due to signals that would normally cause a core dump. +Logging is done via +.Xr log 9 +with a log level of +.Dv LOG_INFO . +.It Dv PROC_LOGSIGEXIT_FORCE_DISABLE +Disables the logging of exits due to signals that would normally cause a core +dump. +.It Dv PROC_LOGSIGEXIT_NOFORCE +The logging behavior is delegated to the +.Xr sysctl 3 +MIB variable +.Va kern.logsigexit . +.El +.It Dv PROC_LOGSIGEXIT_STATUS +Returns the current status of logging for the target process. +The +.Va arg +parameter must point to an integer variable, where one of the following values +is written: +.Bl -tag -width PROC_LOGSIGEXIT_FORCE_DISABLE +.It Dv PROC_LOGSIGEXIT_FORCE_ENABLE +.It Dv PROC_LOGSIGEXIT_FORCE_DISABLE +.It Dv PROC_LOGSIGEXIT_NOFORCE +.El .It Dv PROC_PROTMAX_CTL Controls implicit application of PROT_MAX protection equal to the .Fa prot Index: sys/compat/freebsd32/freebsd32_misc.c =================================================================== --- sys/compat/freebsd32/freebsd32_misc.c +++ sys/compat/freebsd32/freebsd32_misc.c @@ -3367,6 +3367,7 @@ case PROC_STACKGAP_CTL: case PROC_TRACE_CTL: case PROC_TRAPCAP_CTL: + case PROC_LOGSIGEXIT_CTL: error = copyin(PTRIN(uap->data), &flags, sizeof(flags)); if (error != 0) return (error); @@ -3400,6 +3401,7 @@ case PROC_STACKGAP_STATUS: case PROC_TRACE_STATUS: case PROC_TRAPCAP_STATUS: + case PROC_LOGSIGEXIT_STATUS: data = &flags; break; case PROC_PDEATHSIG_CTL: @@ -3431,6 +3433,7 @@ case PROC_STACKGAP_STATUS: case PROC_TRACE_STATUS: case PROC_TRAPCAP_STATUS: + case PROC_LOGSIGEXIT_STATUS: if (error == 0) error = copyout(&flags, uap->data, sizeof(flags)); break; Index: sys/kern/kern_fork.c =================================================================== --- sys/kern/kern_fork.c +++ sys/kern/kern_fork.c @@ -469,7 +469,8 @@ p2->p_flag2 = p1->p_flag2 & (P2_ASLR_DISABLE | P2_ASLR_ENABLE | P2_ASLR_IGNSTART | P2_NOTRACE | P2_NOTRACE_EXEC | P2_PROTMAX_ENABLE | P2_PROTMAX_DISABLE | P2_TRAPCAP | - P2_STKGAP_DISABLE | P2_STKGAP_DISABLE_EXEC); + P2_STKGAP_DISABLE | P2_STKGAP_DISABLE_EXEC | P2_LOGSIGEXIT_CTL | + P2_LOGSIGEXIT_ENABLE); p2->p_swtick = ticks; if (p1->p_flag & P_PROFIL) startprofclock(p2); Index: sys/kern/kern_procctl.c =================================================================== --- sys/kern/kern_procctl.c +++ sys/kern/kern_procctl.c @@ -569,6 +569,42 @@ return (0); } +static int +logsigexit_ctl(struct thread *td, struct proc *p, int state) +{ + + PROC_LOCK_ASSERT(p, MA_OWNED); + + switch (state) { + case PROC_LOGSIGEXIT_CTL_NOFORCE: + p->p_flag2 &= ~(P2_LOGSIGEXIT_CTL | P2_LOGSIGEXIT_ENABLE); + break; + case PROC_LOGSIGEXIT_CTL_FORCE_ENABLE: + p->p_flag2 |= P2_LOGSIGEXIT_CTL | P2_LOGSIGEXIT_ENABLE; + break; + case PROC_LOGSIGEXIT_CTL_FORCE_DISABLE: + p->p_flag2 |= P2_LOGSIGEXIT_CTL; + p->p_flag2 &= ~P2_LOGSIGEXIT_ENABLE; + break; + default: + return (EINVAL); + } + return (0); +} + +static int +logsigexit_status(struct thread *td, struct proc *p, int *data) +{ + + if ((p->p_flag2 & P2_LOGSIGEXIT_CTL) == 0) + *data = PROC_LOGSIGEXIT_CTL_NOFORCE; + else if ((p->p_flag2 & P2_LOGSIGEXIT_ENABLE) != 0) + *data = PROC_LOGSIGEXIT_CTL_FORCE_ENABLE; + else + *data = PROC_LOGSIGEXIT_CTL_FORCE_DISABLE; + return (0); +} + #ifndef _SYS_SYSPROTO_H_ struct procctl_args { idtype_t idtype; @@ -600,6 +636,7 @@ case PROC_STACKGAP_CTL: case PROC_TRACE_CTL: case PROC_TRAPCAP_CTL: + case PROC_LOGSIGEXIT_CTL: error = copyin(uap->data, &flags, sizeof(flags)); if (error != 0) return (error); @@ -631,6 +668,7 @@ case PROC_STACKGAP_STATUS: case PROC_TRACE_STATUS: case PROC_TRAPCAP_STATUS: + case PROC_LOGSIGEXIT_STATUS: data = &flags; break; case PROC_PDEATHSIG_CTL: @@ -661,6 +699,7 @@ case PROC_STACKGAP_STATUS: case PROC_TRACE_STATUS: case PROC_TRAPCAP_STATUS: + case PROC_LOGSIGEXIT_STATUS: if (error == 0) error = copyout(&flags, uap->data, sizeof(flags)); break; @@ -710,6 +749,10 @@ return (trapcap_ctl(td, p, *(int *)data)); case PROC_TRAPCAP_STATUS: return (trapcap_status(td, p, data)); + case PROC_LOGSIGEXIT_CTL: + return (logsigexit_ctl(td, p, *(int *)data)); + case PROC_LOGSIGEXIT_STATUS: + return (logsigexit_status(td, p, data)); default: return (EINVAL); } @@ -772,6 +815,7 @@ case PROC_REAP_KILL: case PROC_TRACE_CTL: case PROC_TRAPCAP_CTL: + case PROC_LOGSIGEXIT_CTL: sx_slock(&proctree_lock); tree_locked = true; break; @@ -788,6 +832,7 @@ case PROC_STACKGAP_STATUS: case PROC_TRACE_STATUS: case PROC_TRAPCAP_STATUS: + case PROC_LOGSIGEXIT_STATUS: tree_locked = false; break; default: Index: sys/kern/kern_sig.c =================================================================== --- sys/kern/kern_sig.c +++ sys/kern/kern_sig.c @@ -3119,9 +3119,15 @@ sigexit(struct thread *td, int sig) { struct proc *p = td->td_proc; + bool logexit; PROC_LOCK_ASSERT(p, MA_OWNED); p->p_acflag |= AXSIG; + if ((p->p_flag2 & P2_LOGSIGEXIT_CTL) == 0) + logexit = kern_logsigexit != 0; + else + logexit = (p->p_flag2 & P2_LOGSIGEXIT_ENABLE) != 0; + /* * We must be single-threading to generate a core dump. This * ensures that the registers in the core file are up-to-date. @@ -3143,7 +3149,7 @@ */ if (coredump(td) == 0) sig |= WCOREFLAG; - if (kern_logsigexit) + if (logexit) log(LOG_INFO, "pid %d (%s), jid %d, uid %d: exited on " "signal %d%s\n", p->p_pid, p->p_comm, Index: sys/sys/proc.h =================================================================== --- sys/sys/proc.h +++ sys/sys/proc.h @@ -765,6 +765,8 @@ #define P2_PROTMAX_DISABLE 0x00000400 /* Force disable implied PROT_MAX. */ #define P2_STKGAP_DISABLE 0x00000800 /* Disable stack gap for MAP_STACK */ #define P2_STKGAP_DISABLE_EXEC 0x00001000 /* Stack gap disabled after exec */ +#define P2_LOGSIGEXIT_ENABLE 0x00002000 /* Disable logging on sigexit */ +#define P2_LOGSIGEXIT_CTL 0x00004000 /* Override kern.logsigexit */ /* Flags protected by proctree_lock, kept in p_treeflags. */ #define P_TREE_ORPHANED 0x00000001 /* Reparented, on orphan list */ Index: sys/sys/procctl.h =================================================================== --- sys/sys/procctl.h +++ sys/sys/procctl.h @@ -63,6 +63,8 @@ #define PROC_PROTMAX_STATUS 16 /* query implicit PROT_MAX status */ #define PROC_STACKGAP_CTL 17 /* en/dis stack gap on MAP_STACK */ #define PROC_STACKGAP_STATUS 18 /* query stack gap */ +#define PROC_LOGSIGEXIT_CTL 19 /* en/dis logging on sigexit */ +#define PROC_LOGSIGEXIT_STATUS 20 /* query logging on sigexit */ /* Operations for PROC_SPROTECT (passed in integer arg). */ #define PPROT_OP(x) ((x) & 0xf) @@ -141,6 +143,10 @@ #define PROC_STACKGAP_ENABLE_EXEC 0x0004 #define PROC_STACKGAP_DISABLE_EXEC 0x0008 +#define PROC_LOGSIGEXIT_CTL_NOFORCE 1 +#define PROC_LOGSIGEXIT_CTL_FORCE_ENABLE 2 +#define PROC_LOGSIGEXIT_CTL_FORCE_DISABLE 3 + #ifndef _KERNEL __BEGIN_DECLS int procctl(idtype_t, id_t, int, void *); Index: usr.bin/proccontrol/proccontrol.1 =================================================================== --- usr.bin/proccontrol/proccontrol.1 +++ usr.bin/proccontrol/proccontrol.1 @@ -28,7 +28,7 @@ .\" .\" $FreeBSD$ .\" -.Dd June 28, 2019 +.Dd October 4, 2019 .Dt PROCCONTROL 1 .Os .Sh NAME @@ -56,7 +56,7 @@ Possible values for .Ar mode are: -.Bl -tag -width trapcap +.Bl -tag -width logsigexit .It Ar aslr Control the Address Space Layout Randomization. Only applicable to the new process spawned. @@ -71,6 +71,9 @@ .Xr mmap 2 . .It Ar kpti Controls the KPTI enable, AMD64 only. +.It Ar logsigexit +Controls the logging of exits due to a signal that would normally cause a core +dump. .El .Pp The Index: usr.bin/proccontrol/proccontrol.c =================================================================== --- usr.bin/proccontrol/proccontrol.c +++ usr.bin/proccontrol/proccontrol.c @@ -48,6 +48,7 @@ #ifdef PROC_KPTI_CTL MODE_KPTI, #endif + MODE_LOGSIGEXIT, }; static pid_t @@ -75,7 +76,7 @@ { fprintf(stderr, "Usage: proccontrol -m (aslr|protmax|trace|trapcap|" - "stackgap"KPTI_USAGE") [-q] " + "stackgap"KPTI_USAGE"|logsigexit) [-q] " "[-s (enable|disable)] [-p pid | command]\n"); exit(1); } @@ -108,6 +109,8 @@ else if (strcmp(optarg, "kpti") == 0) mode = MODE_KPTI; #endif + else if (strcmp(optarg, "logsigexit") == 0) + mode = MODE_LOGSIGEXIT; else usage(); break; @@ -164,6 +167,10 @@ error = procctl(P_PID, pid, PROC_KPTI_STATUS, &arg); break; #endif + case MODE_LOGSIGEXIT: + error = procctl(P_PID, pid, PROC_LOGSIGEXIT_STATUS, + &arg); + break; default: usage(); break; @@ -259,6 +266,19 @@ printf(", not active\n"); break; #endif + case MODE_LOGSIGEXIT: + switch (arg) { + case PROC_LOGSIGEXIT_CTL_NOFORCE: + printf("not forced\n"); + break; + case PROC_LOGSIGEXIT_CTL_FORCE_ENABLE: + printf("force enabled\n"); + break; + case PROC_LOGSIGEXIT_CTL_FORCE_DISABLE: + printf("force disabled\n"); + break; + } + break; } } else { switch (mode) { @@ -295,6 +315,11 @@ error = procctl(P_PID, pid, PROC_KPTI_CTL, &arg); break; #endif + case MODE_LOGSIGEXIT: + arg = enable ? PROC_LOGSIGEXIT_CTL_FORCE_ENABLE : + PROC_LOGSIGEXIT_CTL_FORCE_DISABLE; + error = procctl(P_PID, pid, PROC_LOGSIGEXIT_CTL, &arg); + break; default: usage(); break;