1*d5bc81e6SKyle Evans /* 2*d5bc81e6SKyle Evans * SPDX-License-Identifier: BSD-3-Clause 3*d5bc81e6SKyle Evans * 4*d5bc81e6SKyle Evans * Copyright (c) 1982, 1986, 1989, 1991, 1993 5*d5bc81e6SKyle Evans * The Regents of the University of California. All rights reserved. 6*d5bc81e6SKyle Evans * (c) UNIX System Laboratories, Inc. 7*d5bc81e6SKyle Evans * All or some portions of this file are derived from material licensed 8*d5bc81e6SKyle Evans * to the University of California by American Telephone and Telegraph 9*d5bc81e6SKyle Evans * Co. or Unix System Laboratories, Inc. and are reproduced herein with 10*d5bc81e6SKyle Evans * the permission of UNIX System Laboratories, Inc. 11*d5bc81e6SKyle Evans * 12*d5bc81e6SKyle Evans * Redistribution and use in source and binary forms, with or without 13*d5bc81e6SKyle Evans * modification, are permitted provided that the following conditions 14*d5bc81e6SKyle Evans * are met: 15*d5bc81e6SKyle Evans * 1. Redistributions of source code must retain the above copyright 16*d5bc81e6SKyle Evans * notice, this list of conditions and the following disclaimer. 17*d5bc81e6SKyle Evans * 2. Redistributions in binary form must reproduce the above copyright 18*d5bc81e6SKyle Evans * notice, this list of conditions and the following disclaimer in the 19*d5bc81e6SKyle Evans * documentation and/or other materials provided with the distribution. 20*d5bc81e6SKyle Evans * 3. Neither the name of the University nor the names of its contributors 21*d5bc81e6SKyle Evans * may be used to endorse or promote products derived from this software 22*d5bc81e6SKyle Evans * without specific prior written permission. 23*d5bc81e6SKyle Evans * 24*d5bc81e6SKyle Evans * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 25*d5bc81e6SKyle Evans * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 26*d5bc81e6SKyle Evans * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 27*d5bc81e6SKyle Evans * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 28*d5bc81e6SKyle Evans * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 29*d5bc81e6SKyle Evans * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 30*d5bc81e6SKyle Evans * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 31*d5bc81e6SKyle Evans * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 32*d5bc81e6SKyle Evans * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 33*d5bc81e6SKyle Evans * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 34*d5bc81e6SKyle Evans * SUCH DAMAGE. 35*d5bc81e6SKyle Evans */ 36*d5bc81e6SKyle Evans 37*d5bc81e6SKyle Evans #include <sys/param.h> 38*d5bc81e6SKyle Evans #include <sys/acct.h> 39*d5bc81e6SKyle Evans #include <sys/compressor.h> 40*d5bc81e6SKyle Evans #include <sys/jail.h> 41*d5bc81e6SKyle Evans #include <sys/lock.h> 42*d5bc81e6SKyle Evans #include <sys/mutex.h> 43*d5bc81e6SKyle Evans #include <sys/proc.h> 44*d5bc81e6SKyle Evans #include <sys/signalvar.h> 45*d5bc81e6SKyle Evans #include <sys/racct.h> 46*d5bc81e6SKyle Evans #include <sys/resourcevar.h> 47*d5bc81e6SKyle Evans #include <sys/sysctl.h> 48*d5bc81e6SKyle Evans #include <sys/syslog.h> 49*d5bc81e6SKyle Evans #include <sys/ucoredump.h> 50*d5bc81e6SKyle Evans #include <sys/wait.h> 51*d5bc81e6SKyle Evans 52*d5bc81e6SKyle Evans static int coredump(struct thread *td); 53*d5bc81e6SKyle Evans 54*d5bc81e6SKyle Evans int compress_user_cores = 0; 55*d5bc81e6SKyle Evans 56*d5bc81e6SKyle Evans static int kern_logsigexit = 1; 57*d5bc81e6SKyle Evans SYSCTL_INT(_kern, KERN_LOGSIGEXIT, logsigexit, CTLFLAG_RW, 58*d5bc81e6SKyle Evans &kern_logsigexit, 0, 59*d5bc81e6SKyle Evans "Log processes quitting on abnormal signals to syslog(3)"); 60*d5bc81e6SKyle Evans 61*d5bc81e6SKyle Evans static int sugid_coredump; 62*d5bc81e6SKyle Evans SYSCTL_INT(_kern, OID_AUTO, sugid_coredump, CTLFLAG_RWTUN, 63*d5bc81e6SKyle Evans &sugid_coredump, 0, "Allow setuid and setgid processes to dump core"); 64*d5bc81e6SKyle Evans 65*d5bc81e6SKyle Evans static int do_coredump = 1; 66*d5bc81e6SKyle Evans SYSCTL_INT(_kern, OID_AUTO, coredump, CTLFLAG_RW, 67*d5bc81e6SKyle Evans &do_coredump, 0, "Enable/Disable coredumps"); 68*d5bc81e6SKyle Evans 69*d5bc81e6SKyle Evans static int 70*d5bc81e6SKyle Evans sysctl_compress_user_cores(SYSCTL_HANDLER_ARGS) 71*d5bc81e6SKyle Evans { 72*d5bc81e6SKyle Evans int error, val; 73*d5bc81e6SKyle Evans 74*d5bc81e6SKyle Evans val = compress_user_cores; 75*d5bc81e6SKyle Evans error = sysctl_handle_int(oidp, &val, 0, req); 76*d5bc81e6SKyle Evans if (error != 0 || req->newptr == NULL) 77*d5bc81e6SKyle Evans return (error); 78*d5bc81e6SKyle Evans if (val != 0 && !compressor_avail(val)) 79*d5bc81e6SKyle Evans return (EINVAL); 80*d5bc81e6SKyle Evans compress_user_cores = val; 81*d5bc81e6SKyle Evans return (error); 82*d5bc81e6SKyle Evans } 83*d5bc81e6SKyle Evans SYSCTL_PROC(_kern, OID_AUTO, compress_user_cores, 84*d5bc81e6SKyle Evans CTLTYPE_INT | CTLFLAG_RWTUN | CTLFLAG_NEEDGIANT, 0, sizeof(int), 85*d5bc81e6SKyle Evans sysctl_compress_user_cores, "I", 86*d5bc81e6SKyle Evans "Enable compression of user corefiles (" 87*d5bc81e6SKyle Evans __XSTRING(COMPRESS_GZIP) " = gzip, " 88*d5bc81e6SKyle Evans __XSTRING(COMPRESS_ZSTD) " = zstd)"); 89*d5bc81e6SKyle Evans 90*d5bc81e6SKyle Evans int compress_user_cores_level = 6; 91*d5bc81e6SKyle Evans SYSCTL_INT(_kern, OID_AUTO, compress_user_cores_level, CTLFLAG_RWTUN, 92*d5bc81e6SKyle Evans &compress_user_cores_level, 0, 93*d5bc81e6SKyle Evans "Corefile compression level"); 94*d5bc81e6SKyle Evans 95*d5bc81e6SKyle Evans /* 96*d5bc81e6SKyle Evans * Force the current process to exit with the specified signal, dumping core 97*d5bc81e6SKyle Evans * if appropriate. We bypass the normal tests for masked and caught signals, 98*d5bc81e6SKyle Evans * allowing unrecoverable failures to terminate the process without changing 99*d5bc81e6SKyle Evans * signal state. Mark the accounting record with the signal termination. 100*d5bc81e6SKyle Evans * If dumping core, save the signal number for the debugger. Calls exit and 101*d5bc81e6SKyle Evans * does not return. 102*d5bc81e6SKyle Evans */ 103*d5bc81e6SKyle Evans void 104*d5bc81e6SKyle Evans sigexit(struct thread *td, int sig) 105*d5bc81e6SKyle Evans { 106*d5bc81e6SKyle Evans struct proc *p = td->td_proc; 107*d5bc81e6SKyle Evans const char *coreinfo; 108*d5bc81e6SKyle Evans int rv; 109*d5bc81e6SKyle Evans bool logexit; 110*d5bc81e6SKyle Evans 111*d5bc81e6SKyle Evans PROC_LOCK_ASSERT(p, MA_OWNED); 112*d5bc81e6SKyle Evans proc_set_p2_wexit(p); 113*d5bc81e6SKyle Evans 114*d5bc81e6SKyle Evans p->p_acflag |= AXSIG; 115*d5bc81e6SKyle Evans if ((p->p_flag2 & P2_LOGSIGEXIT_CTL) == 0) 116*d5bc81e6SKyle Evans logexit = kern_logsigexit != 0; 117*d5bc81e6SKyle Evans else 118*d5bc81e6SKyle Evans logexit = (p->p_flag2 & P2_LOGSIGEXIT_ENABLE) != 0; 119*d5bc81e6SKyle Evans 120*d5bc81e6SKyle Evans /* 121*d5bc81e6SKyle Evans * We must be single-threading to generate a core dump. This 122*d5bc81e6SKyle Evans * ensures that the registers in the core file are up-to-date. 123*d5bc81e6SKyle Evans * Also, the ELF dump handler assumes that the thread list doesn't 124*d5bc81e6SKyle Evans * change out from under it. 125*d5bc81e6SKyle Evans * 126*d5bc81e6SKyle Evans * XXX If another thread attempts to single-thread before us 127*d5bc81e6SKyle Evans * (e.g. via fork()), we won't get a dump at all. 128*d5bc81e6SKyle Evans */ 129*d5bc81e6SKyle Evans if (sig_do_core(sig) && thread_single(p, SINGLE_NO_EXIT) == 0) { 130*d5bc81e6SKyle Evans p->p_sig = sig; 131*d5bc81e6SKyle Evans /* 132*d5bc81e6SKyle Evans * Log signals which would cause core dumps 133*d5bc81e6SKyle Evans * (Log as LOG_INFO to appease those who don't want 134*d5bc81e6SKyle Evans * these messages.) 135*d5bc81e6SKyle Evans * XXX : Todo, as well as euid, write out ruid too 136*d5bc81e6SKyle Evans * Note that coredump() drops proc lock. 137*d5bc81e6SKyle Evans */ 138*d5bc81e6SKyle Evans rv = coredump(td); 139*d5bc81e6SKyle Evans switch (rv) { 140*d5bc81e6SKyle Evans case 0: 141*d5bc81e6SKyle Evans sig |= WCOREFLAG; 142*d5bc81e6SKyle Evans coreinfo = " (core dumped)"; 143*d5bc81e6SKyle Evans break; 144*d5bc81e6SKyle Evans case EFAULT: 145*d5bc81e6SKyle Evans coreinfo = " (no core dump - bad address)"; 146*d5bc81e6SKyle Evans break; 147*d5bc81e6SKyle Evans case EINVAL: 148*d5bc81e6SKyle Evans coreinfo = " (no core dump - invalid argument)"; 149*d5bc81e6SKyle Evans break; 150*d5bc81e6SKyle Evans case EFBIG: 151*d5bc81e6SKyle Evans coreinfo = " (no core dump - too large)"; 152*d5bc81e6SKyle Evans break; 153*d5bc81e6SKyle Evans default: 154*d5bc81e6SKyle Evans coreinfo = " (no core dump - other error)"; 155*d5bc81e6SKyle Evans break; 156*d5bc81e6SKyle Evans } 157*d5bc81e6SKyle Evans if (logexit) 158*d5bc81e6SKyle Evans log(LOG_INFO, 159*d5bc81e6SKyle Evans "pid %d (%s), jid %d, uid %d: exited on " 160*d5bc81e6SKyle Evans "signal %d%s\n", p->p_pid, p->p_comm, 161*d5bc81e6SKyle Evans p->p_ucred->cr_prison->pr_id, 162*d5bc81e6SKyle Evans td->td_ucred->cr_uid, 163*d5bc81e6SKyle Evans sig &~ WCOREFLAG, coreinfo); 164*d5bc81e6SKyle Evans } else 165*d5bc81e6SKyle Evans PROC_UNLOCK(p); 166*d5bc81e6SKyle Evans exit1(td, 0, sig); 167*d5bc81e6SKyle Evans /* NOTREACHED */ 168*d5bc81e6SKyle Evans } 169*d5bc81e6SKyle Evans 170*d5bc81e6SKyle Evans 171*d5bc81e6SKyle Evans /* 172*d5bc81e6SKyle Evans * Dump a process' core. The main routine does some 173*d5bc81e6SKyle Evans * policy checking, and creates the name of the coredump; 174*d5bc81e6SKyle Evans * then it passes on a vnode and a size limit to the process-specific 175*d5bc81e6SKyle Evans * coredump routine if there is one; if there _is not_ one, it returns 176*d5bc81e6SKyle Evans * ENOSYS; otherwise it returns the error from the process-specific routine. 177*d5bc81e6SKyle Evans */ 178*d5bc81e6SKyle Evans static int 179*d5bc81e6SKyle Evans coredump(struct thread *td) 180*d5bc81e6SKyle Evans { 181*d5bc81e6SKyle Evans struct proc *p = td->td_proc; 182*d5bc81e6SKyle Evans off_t limit; 183*d5bc81e6SKyle Evans int error; 184*d5bc81e6SKyle Evans 185*d5bc81e6SKyle Evans PROC_LOCK_ASSERT(p, MA_OWNED); 186*d5bc81e6SKyle Evans MPASS((p->p_flag & P_HADTHREADS) == 0 || p->p_singlethread == td); 187*d5bc81e6SKyle Evans 188*d5bc81e6SKyle Evans if (!do_coredump || (!sugid_coredump && (p->p_flag & P_SUGID) != 0) || 189*d5bc81e6SKyle Evans (p->p_flag2 & P2_NOTRACE) != 0) { 190*d5bc81e6SKyle Evans PROC_UNLOCK(p); 191*d5bc81e6SKyle Evans return (EFAULT); 192*d5bc81e6SKyle Evans } 193*d5bc81e6SKyle Evans 194*d5bc81e6SKyle Evans /* 195*d5bc81e6SKyle Evans * Note that the bulk of limit checking is done after 196*d5bc81e6SKyle Evans * the corefile is created. The exception is if the limit 197*d5bc81e6SKyle Evans * for corefiles is 0, in which case we don't bother 198*d5bc81e6SKyle Evans * creating the corefile at all. This layout means that 199*d5bc81e6SKyle Evans * a corefile is truncated instead of not being created, 200*d5bc81e6SKyle Evans * if it is larger than the limit. 201*d5bc81e6SKyle Evans */ 202*d5bc81e6SKyle Evans limit = (off_t)lim_cur(td, RLIMIT_CORE); 203*d5bc81e6SKyle Evans if (limit == 0 || racct_get_available(p, RACCT_CORE) == 0) { 204*d5bc81e6SKyle Evans PROC_UNLOCK(p); 205*d5bc81e6SKyle Evans return (EFBIG); 206*d5bc81e6SKyle Evans } 207*d5bc81e6SKyle Evans 208*d5bc81e6SKyle Evans error = coredump_vnode(td, limit); 209*d5bc81e6SKyle Evans PROC_LOCK_ASSERT(p, MA_NOTOWNED); 210*d5bc81e6SKyle Evans 211*d5bc81e6SKyle Evans return (error); 212*d5bc81e6SKyle Evans } 213