diff --git a/lib/libsys/procctl.2 b/lib/libsys/procctl.2 --- a/lib/libsys/procctl.2 +++ b/lib/libsys/procctl.2 @@ -27,7 +27,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.Dd December 4, 2024 +.Dd December 14, 2024 .Dt PROCCTL 2 .Os .Sh NAME @@ -79,7 +79,7 @@ require the caller to have the right to observe the target. .Pp The following commands are supported: -.Bl -tag -width PROC_TRAPCAP_STATUS +.Bl -tag -width PROC_LOGSIGEXIT_STATUS .It Dv PROC_ASLR_CTL Controls Address Space Layout Randomization (ASLR) in program images created @@ -127,6 +127,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 the maximum protection used for .Xr mmap 2 diff --git a/sys/compat/freebsd32/freebsd32_misc.c b/sys/compat/freebsd32/freebsd32_misc.c --- a/sys/compat/freebsd32/freebsd32_misc.c +++ b/sys/compat/freebsd32/freebsd32_misc.c @@ -3860,6 +3860,7 @@ case PROC_TRAPCAP_CTL: case PROC_NO_NEW_PRIVS_CTL: case PROC_WXMAP_CTL: + case PROC_LOGSIGEXIT_CTL: error = copyin(PTRIN(uap->data), &flags, sizeof(flags)); if (error != 0) return (error); @@ -3895,6 +3896,7 @@ case PROC_TRAPCAP_STATUS: case PROC_NO_NEW_PRIVS_STATUS: case PROC_WXMAP_STATUS: + case PROC_LOGSIGEXIT_STATUS: data = &flags; break; case PROC_PDEATHSIG_CTL: @@ -3928,6 +3930,7 @@ case PROC_TRAPCAP_STATUS: case PROC_NO_NEW_PRIVS_STATUS: case PROC_WXMAP_STATUS: + case PROC_LOGSIGEXIT_STATUS: if (error == 0) error = copyout(&flags, uap->data, sizeof(flags)); break; diff --git a/sys/kern/kern_fork.c b/sys/kern/kern_fork.c --- a/sys/kern/kern_fork.c +++ b/sys/kern/kern_fork.c @@ -496,7 +496,8 @@ P2_ASLR_IGNSTART | P2_NOTRACE | P2_NOTRACE_EXEC | P2_PROTMAX_ENABLE | P2_PROTMAX_DISABLE | P2_TRAPCAP | P2_STKGAP_DISABLE | P2_STKGAP_DISABLE_EXEC | P2_NO_NEW_PRIVS | - P2_WXORX_DISABLE | P2_WXORX_ENABLE_EXEC); + P2_WXORX_DISABLE | P2_WXORX_ENABLE_EXEC | P2_LOGSIGEXIT_CTL | + P2_LOGSIGEXIT_ENABLE); p2->p_swtick = ticks; if (p1->p_flag & P_PROFIL) startprofclock(p2); diff --git a/sys/kern/kern_procctl.c b/sys/kern/kern_procctl.c --- a/sys/kern/kern_procctl.c +++ b/sys/kern/kern_procctl.c @@ -945,6 +945,46 @@ return (0); } +static int +logsigexit_ctl(struct thread *td, struct proc *p, void *data) +{ + int state; + + PROC_LOCK_ASSERT(p, MA_OWNED); + state = *(int *)data; + + 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, void *data) +{ + int state; + + if ((p->p_flag2 & P2_LOGSIGEXIT_CTL) == 0) + state = PROC_LOGSIGEXIT_CTL_NOFORCE; + else if ((p->p_flag2 & P2_LOGSIGEXIT_ENABLE) != 0) + state = PROC_LOGSIGEXIT_CTL_FORCE_ENABLE; + else + state = PROC_LOGSIGEXIT_CTL_FORCE_DISABLE; + *(int *)data = state; + return (0); +} + enum { PCTL_SLOCKED, PCTL_XLOCKED, @@ -1100,6 +1140,18 @@ .need_candebug = false, .copyin_sz = 0, .copyout_sz = sizeof(int), .exec = wxmap_status, .copyout_on_error = false, }, + [PROC_LOGSIGEXIT_CTL] = + { .lock_tree = PCTL_SLOCKED, .one_proc = true, + .esrch_is_einval = false, .no_nonnull_data = false, + .need_candebug = true, + .copyin_sz = sizeof(int), .copyout_sz = 0, + .exec = logsigexit_ctl, .copyout_on_error = false, }, + [PROC_LOGSIGEXIT_STATUS] = + { .lock_tree = PCTL_UNLOCKED, .one_proc = true, + .esrch_is_einval = false, .no_nonnull_data = false, + .need_candebug = false, + .copyin_sz = 0, .copyout_sz = sizeof(int), + .exec = logsigexit_status, .copyout_on_error = false, }, }; int diff --git a/sys/kern/kern_sig.c b/sys/kern/kern_sig.c --- a/sys/kern/kern_sig.c +++ b/sys/kern/kern_sig.c @@ -3606,11 +3606,17 @@ struct proc *p = td->td_proc; const char *coreinfo; int rv; + bool logexit; PROC_LOCK_ASSERT(p, MA_OWNED); proc_set_p2_wexit(p); 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. @@ -3649,7 +3655,7 @@ coreinfo = " (no core dump - other error)"; break; } - 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, diff --git a/sys/sys/proc.h b/sys/sys/proc.h --- a/sys/sys/proc.h +++ b/sys/sys/proc.h @@ -886,6 +886,9 @@ #define P2_MEMBAR_GLOBE 0x00400000 /* membar global expedited registered */ +#define P2_LOGSIGEXIT_ENABLE 0x00800000 /* Disable logging on sigexit */ +#define P2_LOGSIGEXIT_CTL 0x01000000 /* Override kern.logsigexit */ + /* Flags protected by proctree_lock, kept in p_treeflags. */ #define P_TREE_ORPHANED 0x00000001 /* Reparented, on orphan list */ #define P_TREE_FIRST_ORPHAN 0x00000002 /* First element of orphan diff --git a/sys/sys/procctl.h b/sys/sys/procctl.h --- a/sys/sys/procctl.h +++ b/sys/sys/procctl.h @@ -65,6 +65,8 @@ #define PROC_NO_NEW_PRIVS_STATUS 20 /* query suid/sgid disabled status */ #define PROC_WXMAP_CTL 21 /* control W^X */ #define PROC_WXMAP_STATUS 22 /* query W^X */ +#define PROC_LOGSIGEXIT_CTL 23 /* en/dis logging on sigexit */ +#define PROC_LOGSIGEXIT_STATUS 24 /* query logging on sigexit */ /* Operations for PROC_SPROTECT (passed in integer arg). */ #define PPROT_OP(x) ((x) & 0xf) @@ -153,6 +155,10 @@ #define PROC_WX_MAPPINGS_DISALLOW_EXEC 0x0002 #define PROC_WXORX_ENFORCE 0x80000000 +#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 *); diff --git a/usr.bin/proccontrol/proccontrol.1 b/usr.bin/proccontrol/proccontrol.1 --- a/usr.bin/proccontrol/proccontrol.1 +++ b/usr.bin/proccontrol/proccontrol.1 @@ -25,7 +25,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.Dd August 23, 2024 +.Dd December 14, 2024 .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. @@ -79,6 +79,9 @@ .It Ar la48 Control limiting usermode process address space to 48 bits of address, AMD64 only, on machines capable of 57-bit addressing. +.It Ar logsigexit +Controls the logging of exits due to a signal that would normally cause a core +dump. .El .Pp The diff --git a/usr.bin/proccontrol/proccontrol.c b/usr.bin/proccontrol/proccontrol.c --- a/usr.bin/proccontrol/proccontrol.c +++ b/usr.bin/proccontrol/proccontrol.c @@ -51,6 +51,7 @@ MODE_LA57, MODE_LA48, #endif + MODE_LOGSIGEXIT, }; static const struct { @@ -71,6 +72,7 @@ { MODE_LA57, "la57" }, { MODE_LA48, "la48" }, #endif + { MODE_LOGSIGEXIT, "logsigexit" }, }; static pid_t @@ -194,6 +196,10 @@ error = procctl(P_PID, pid, PROC_LA_STATUS, &arg); break; #endif + case MODE_LOGSIGEXIT: + error = procctl(P_PID, pid, PROC_LOGSIGEXIT_STATUS, + &arg); + break; default: usage(); break; @@ -331,6 +337,19 @@ printf(", la57 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) { @@ -390,6 +409,11 @@ error = procctl(P_PID, pid, PROC_LA_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;