1 /* 2 * SPDX-License-Identifier: BSD-3-Clause AND BSD-2-Clause 3 * 4 * Copyright (c) 1982, 1986, 1989, 1991, 1993 5 * The Regents of the University of California. All rights reserved. 6 * (c) UNIX System Laboratories, Inc. 7 * All or some portions of this file are derived from material licensed 8 * to the University of California by American Telephone and Telegraph 9 * Co. or Unix System Laboratories, Inc. and are reproduced herein with 10 * the permission of UNIX System Laboratories, Inc. 11 * 12 * Redistribution and use in source and binary forms, with or without 13 * modification, are permitted provided that the following conditions 14 * are met: 15 * 1. Redistributions of source code must retain the above copyright 16 * notice, this list of conditions and the following disclaimer. 17 * 2. Redistributions in binary form must reproduce the above copyright 18 * notice, this list of conditions and the following disclaimer in the 19 * documentation and/or other materials provided with the distribution. 20 * 3. Neither the name of the University nor the names of its contributors 21 * may be used to endorse or promote products derived from this software 22 * without specific prior written permission. 23 * 24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 34 * SUCH DAMAGE. 35 * - kern_sig.c 36 */ 37 /* 38 * Copyright (c) 1993, David Greenman 39 * All rights reserved. 40 * 41 * Redistribution and use in source and binary forms, with or without 42 * modification, are permitted provided that the following conditions 43 * are met: 44 * 1. Redistributions of source code must retain the above copyright 45 * notice, this list of conditions and the following disclaimer. 46 * 2. Redistributions in binary form must reproduce the above copyright 47 * notice, this list of conditions and the following disclaimer in the 48 * documentation and/or other materials provided with the distribution. 49 * 50 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 51 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 52 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 53 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 54 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 55 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 56 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 57 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 58 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 59 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 60 * SUCH DAMAGE. 61 * -kern_exec.c 62 */ 63 64 #include <sys/systm.h> 65 #include <sys/acct.h> 66 #include <sys/compressor.h> 67 #include <sys/devctl.h> 68 #include <sys/fcntl.h> 69 #include <sys/jail.h> 70 #include <sys/limits.h> 71 #include <sys/namei.h> 72 #include <sys/proc.h> 73 #include <sys/sbuf.h> 74 #include <sys/stat.h> 75 #include <sys/sysctl.h> 76 #include <sys/sysent.h> 77 #include <sys/syslog.h> 78 #include <sys/ucoredump.h> 79 #include <sys/unistd.h> 80 #include <sys/vnode.h> 81 82 #include <security/audit/audit.h> 83 84 #define GZIP_SUFFIX ".gz" 85 #define ZSTD_SUFFIX ".zst" 86 87 #define MAX_NUM_CORE_FILES 100000 88 #ifndef NUM_CORE_FILES 89 #define NUM_CORE_FILES 5 90 #endif 91 92 static coredumper_handle_fn coredump_vnode; 93 static struct coredumper vnode_coredumper = { 94 .cd_name = "vnode_coredumper", 95 .cd_handle = coredump_vnode, 96 }; 97 98 SYSINIT(vnode_coredumper_register, SI_SUB_EXEC, SI_ORDER_ANY, 99 coredumper_register, &vnode_coredumper); 100 101 _Static_assert(NUM_CORE_FILES >= 0 && NUM_CORE_FILES <= MAX_NUM_CORE_FILES, 102 "NUM_CORE_FILES is out of range (0 to " __STRING(MAX_NUM_CORE_FILES) ")"); 103 static int num_cores = NUM_CORE_FILES; 104 105 static int capmode_coredump; 106 SYSCTL_INT(_kern, OID_AUTO, capmode_coredump, CTLFLAG_RWTUN, 107 &capmode_coredump, 0, "Allow processes in capability mode to dump core"); 108 109 static int set_core_nodump_flag = 0; 110 SYSCTL_INT(_kern, OID_AUTO, nodump_coredump, CTLFLAG_RW, &set_core_nodump_flag, 111 0, "Enable setting the NODUMP flag on coredump files"); 112 113 static int coredump_devctl = 0; 114 SYSCTL_INT(_kern, OID_AUTO, coredump_devctl, CTLFLAG_RW, &coredump_devctl, 115 0, "Generate a devctl notification when processes coredump"); 116 117 /* 118 * corefilename[] is protected by the allproc_lock. 119 */ 120 static char corefilename[MAXPATHLEN] = { "%N.core" }; 121 TUNABLE_STR("kern.corefile", corefilename, sizeof(corefilename)); 122 123 static int 124 sysctl_kern_corefile(SYSCTL_HANDLER_ARGS) 125 { 126 int error; 127 128 sx_xlock(&allproc_lock); 129 error = sysctl_handle_string(oidp, corefilename, sizeof(corefilename), 130 req); 131 sx_xunlock(&allproc_lock); 132 133 return (error); 134 } 135 SYSCTL_PROC(_kern, OID_AUTO, corefile, CTLTYPE_STRING | CTLFLAG_RW | 136 CTLFLAG_MPSAFE, 0, 0, sysctl_kern_corefile, "A", 137 "Process corefile name format string"); 138 139 static int 140 sysctl_debug_num_cores_check (SYSCTL_HANDLER_ARGS) 141 { 142 int error; 143 int new_val; 144 145 new_val = num_cores; 146 error = sysctl_handle_int(oidp, &new_val, 0, req); 147 if (error != 0 || req->newptr == NULL) 148 return (error); 149 if (new_val > MAX_NUM_CORE_FILES) 150 new_val = MAX_NUM_CORE_FILES; 151 if (new_val < 0) 152 new_val = 0; 153 num_cores = new_val; 154 return (0); 155 } 156 SYSCTL_PROC(_debug, OID_AUTO, ncores, 157 CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_MPSAFE, 0, sizeof(int), 158 sysctl_debug_num_cores_check, "I", 159 "Maximum number of generated process corefiles while using index format"); 160 161 static void 162 vnode_close_locked(struct thread *td, struct vnode *vp) 163 { 164 165 VOP_UNLOCK(vp); 166 vn_close(vp, FWRITE, td->td_ucred, td); 167 } 168 169 int 170 core_vn_write(const struct coredump_writer *cdw, const void *base, size_t len, 171 off_t offset, enum uio_seg seg, struct ucred *cred, size_t *resid, 172 struct thread *td) 173 { 174 struct coredump_vnode_ctx *ctx = cdw->ctx; 175 176 return (vn_rdwr_inchunks(UIO_WRITE, ctx->vp, __DECONST(void *, base), 177 len, offset, seg, IO_UNIT | IO_DIRECT | IO_RANGELOCKED, 178 cred, ctx->fcred, resid, td)); 179 } 180 181 int 182 core_vn_extend(const struct coredump_writer *cdw, off_t newsz, 183 struct ucred *cred) 184 { 185 struct coredump_vnode_ctx *ctx = cdw->ctx; 186 struct mount *mp; 187 int error; 188 189 error = vn_start_write(ctx->vp, &mp, V_WAIT); 190 if (error != 0) 191 return (error); 192 vn_lock(ctx->vp, LK_EXCLUSIVE | LK_RETRY); 193 error = vn_truncate_locked(ctx->vp, newsz, false, cred); 194 VOP_UNLOCK(ctx->vp); 195 vn_finished_write(mp); 196 return (error); 197 } 198 199 /* 200 * If the core format has a %I in it, then we need to check 201 * for existing corefiles before defining a name. 202 * To do this we iterate over 0..ncores to find a 203 * non-existing core file name to use. If all core files are 204 * already used we choose the oldest one. 205 */ 206 static int 207 corefile_open_last(struct thread *td, char *name, int indexpos, 208 int indexlen, int ncores, struct vnode **vpp) 209 { 210 struct vnode *oldvp, *nextvp, *vp; 211 struct vattr vattr; 212 struct nameidata nd; 213 int error, i, flags, oflags, cmode; 214 char ch; 215 struct timespec lasttime; 216 217 nextvp = oldvp = NULL; 218 cmode = S_IRUSR | S_IWUSR; 219 oflags = VN_OPEN_NOAUDIT | VN_OPEN_NAMECACHE | 220 (capmode_coredump ? VN_OPEN_NOCAPCHECK : 0); 221 222 for (i = 0; i < ncores; i++) { 223 flags = O_CREAT | FWRITE | O_NOFOLLOW; 224 225 ch = name[indexpos + indexlen]; 226 (void)snprintf(name + indexpos, indexlen + 1, "%.*u", indexlen, 227 i); 228 name[indexpos + indexlen] = ch; 229 230 NDINIT(&nd, LOOKUP, NOFOLLOW, UIO_SYSSPACE, name); 231 error = vn_open_cred(&nd, &flags, cmode, oflags, td->td_ucred, 232 NULL); 233 if (error != 0) 234 break; 235 236 vp = nd.ni_vp; 237 NDFREE_PNBUF(&nd); 238 if ((flags & O_CREAT) == O_CREAT) { 239 nextvp = vp; 240 break; 241 } 242 243 error = VOP_GETATTR(vp, &vattr, td->td_ucred); 244 if (error != 0) { 245 vnode_close_locked(td, vp); 246 break; 247 } 248 249 if (oldvp == NULL || 250 lasttime.tv_sec > vattr.va_mtime.tv_sec || 251 (lasttime.tv_sec == vattr.va_mtime.tv_sec && 252 lasttime.tv_nsec >= vattr.va_mtime.tv_nsec)) { 253 if (oldvp != NULL) 254 vn_close(oldvp, FWRITE, td->td_ucred, td); 255 oldvp = vp; 256 VOP_UNLOCK(oldvp); 257 lasttime = vattr.va_mtime; 258 } else { 259 vnode_close_locked(td, vp); 260 } 261 } 262 263 if (oldvp != NULL) { 264 if (nextvp == NULL) { 265 if ((td->td_proc->p_flag & P_SUGID) != 0) { 266 error = EFAULT; 267 vn_close(oldvp, FWRITE, td->td_ucred, td); 268 } else { 269 nextvp = oldvp; 270 error = vn_lock(nextvp, LK_EXCLUSIVE); 271 if (error != 0) { 272 vn_close(nextvp, FWRITE, td->td_ucred, 273 td); 274 nextvp = NULL; 275 } 276 } 277 } else { 278 vn_close(oldvp, FWRITE, td->td_ucred, td); 279 } 280 } 281 if (error != 0) { 282 if (nextvp != NULL) 283 vnode_close_locked(td, oldvp); 284 } else { 285 *vpp = nextvp; 286 } 287 288 return (error); 289 } 290 291 /* 292 * corefile_open(comm, uid, pid, td, compress, vpp, namep) 293 * Expand the name described in corefilename, using name, uid, and pid 294 * and open/create core file. 295 * corefilename is a printf-like string, with three format specifiers: 296 * %N name of process ("name") 297 * %P process id (pid) 298 * %U user id (uid) 299 * For example, "%N.core" is the default; they can be disabled completely 300 * by using "/dev/null", or all core files can be stored in "/cores/%U/%N-%P". 301 * This is controlled by the sysctl variable kern.corefile (see above). 302 */ 303 static int 304 corefile_open(const char *comm, uid_t uid, pid_t pid, struct thread *td, 305 int compress, int signum, struct vnode **vpp, char **namep) 306 { 307 struct sbuf sb; 308 struct nameidata nd; 309 const char *format; 310 char *hostname, *name; 311 int cmode, error, flags, i, indexpos, indexlen, oflags, ncores; 312 313 hostname = NULL; 314 format = corefilename; 315 name = malloc(MAXPATHLEN, M_TEMP, M_WAITOK | M_ZERO); 316 indexlen = 0; 317 indexpos = -1; 318 ncores = num_cores; 319 (void)sbuf_new(&sb, name, MAXPATHLEN, SBUF_FIXEDLEN); 320 sx_slock(&allproc_lock); 321 for (i = 0; format[i] != '\0'; i++) { 322 switch (format[i]) { 323 case '%': /* Format character */ 324 i++; 325 switch (format[i]) { 326 case '%': 327 sbuf_putc(&sb, '%'); 328 break; 329 case 'H': /* hostname */ 330 if (hostname == NULL) { 331 hostname = malloc(MAXHOSTNAMELEN, 332 M_TEMP, M_WAITOK); 333 } 334 getcredhostname(td->td_ucred, hostname, 335 MAXHOSTNAMELEN); 336 sbuf_cat(&sb, hostname); 337 break; 338 case 'I': /* autoincrementing index */ 339 if (indexpos != -1) { 340 sbuf_printf(&sb, "%%I"); 341 break; 342 } 343 344 indexpos = sbuf_len(&sb); 345 sbuf_printf(&sb, "%u", ncores - 1); 346 indexlen = sbuf_len(&sb) - indexpos; 347 break; 348 case 'N': /* process name */ 349 sbuf_printf(&sb, "%s", comm); 350 break; 351 case 'P': /* process id */ 352 sbuf_printf(&sb, "%u", pid); 353 break; 354 case 'S': /* signal number */ 355 sbuf_printf(&sb, "%i", signum); 356 break; 357 case 'U': /* user id */ 358 sbuf_printf(&sb, "%u", uid); 359 break; 360 default: 361 log(LOG_ERR, 362 "Unknown format character %c in " 363 "corename `%s'\n", format[i], format); 364 break; 365 } 366 break; 367 default: 368 sbuf_putc(&sb, format[i]); 369 break; 370 } 371 } 372 sx_sunlock(&allproc_lock); 373 free(hostname, M_TEMP); 374 if (compress == COMPRESS_GZIP) 375 sbuf_cat(&sb, GZIP_SUFFIX); 376 else if (compress == COMPRESS_ZSTD) 377 sbuf_cat(&sb, ZSTD_SUFFIX); 378 if (sbuf_error(&sb) != 0) { 379 log(LOG_ERR, "pid %ld (%s), uid (%lu): corename is too " 380 "long\n", (long)pid, comm, (u_long)uid); 381 sbuf_delete(&sb); 382 free(name, M_TEMP); 383 return (ENOMEM); 384 } 385 sbuf_finish(&sb); 386 sbuf_delete(&sb); 387 388 if (indexpos != -1) { 389 error = corefile_open_last(td, name, indexpos, indexlen, ncores, 390 vpp); 391 if (error != 0) { 392 log(LOG_ERR, 393 "pid %d (%s), uid (%u): Path `%s' failed " 394 "on initial open test, error = %d\n", 395 pid, comm, uid, name, error); 396 } 397 } else { 398 cmode = S_IRUSR | S_IWUSR; 399 oflags = VN_OPEN_NOAUDIT | VN_OPEN_NAMECACHE | 400 (capmode_coredump ? VN_OPEN_NOCAPCHECK : 0); 401 flags = O_CREAT | FWRITE | O_NOFOLLOW; 402 if ((td->td_proc->p_flag & P_SUGID) != 0) 403 flags |= O_EXCL; 404 405 NDINIT(&nd, LOOKUP, NOFOLLOW, UIO_SYSSPACE, name); 406 error = vn_open_cred(&nd, &flags, cmode, oflags, td->td_ucred, 407 NULL); 408 if (error == 0) { 409 *vpp = nd.ni_vp; 410 NDFREE_PNBUF(&nd); 411 } 412 } 413 414 if (error != 0) { 415 #ifdef AUDIT 416 audit_proc_coredump(td, name, error); 417 #endif 418 free(name, M_TEMP); 419 return (error); 420 } 421 *namep = name; 422 return (0); 423 } 424 425 /* 426 * The vnode dumper is the traditional coredump handler. Our policy and limits 427 * are generally checked already, so it creates the coredump name and passes on 428 * a vnode and a size limit to the process-specific coredump routine if there is 429 * one. If there _is not_ one, it returns ENOSYS; otherwise it returns the 430 * error from the process-specific routine. 431 */ 432 static int 433 coredump_vnode(struct thread *td, off_t limit) 434 { 435 struct proc *p = td->td_proc; 436 struct ucred *cred = td->td_ucred; 437 struct vnode *vp; 438 struct coredump_vnode_ctx wctx; 439 struct coredump_writer cdw = { }; 440 struct flock lf; 441 struct vattr vattr; 442 size_t fullpathsize; 443 int error, error1, jid, locked, ppid, sig; 444 char *name; /* name of corefile */ 445 void *rl_cookie; 446 char *fullpath, *freepath = NULL; 447 struct sbuf *sb; 448 449 PROC_LOCK_ASSERT(p, MA_OWNED); 450 451 ppid = p->p_oppid; 452 sig = p->p_sig; 453 jid = p->p_ucred->cr_prison->pr_id; 454 PROC_UNLOCK(p); 455 456 error = corefile_open(p->p_comm, cred->cr_uid, p->p_pid, td, 457 compress_user_cores, sig, &vp, &name); 458 if (error != 0) 459 return (error); 460 461 /* 462 * Don't dump to non-regular files or files with links. 463 * Do not dump into system files. Effective user must own the corefile. 464 */ 465 if (vp->v_type != VREG || VOP_GETATTR(vp, &vattr, cred) != 0 || 466 vattr.va_nlink != 1 || (vp->v_vflag & VV_SYSTEM) != 0 || 467 vattr.va_uid != cred->cr_uid) { 468 VOP_UNLOCK(vp); 469 error = EFAULT; 470 goto out; 471 } 472 473 VOP_UNLOCK(vp); 474 475 /* Postpone other writers, including core dumps of other processes. */ 476 rl_cookie = vn_rangelock_wlock(vp, 0, OFF_MAX); 477 478 lf.l_whence = SEEK_SET; 479 lf.l_start = 0; 480 lf.l_len = 0; 481 lf.l_type = F_WRLCK; 482 locked = (VOP_ADVLOCK(vp, (caddr_t)p, F_SETLK, &lf, F_FLOCK) == 0); 483 484 VATTR_NULL(&vattr); 485 vattr.va_size = 0; 486 if (set_core_nodump_flag) 487 vattr.va_flags = UF_NODUMP; 488 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); 489 VOP_SETATTR(vp, &vattr, cred); 490 VOP_UNLOCK(vp); 491 PROC_LOCK(p); 492 p->p_acflag |= ACORE; 493 PROC_UNLOCK(p); 494 495 wctx.vp = vp; 496 wctx.fcred = NOCRED; 497 498 cdw.ctx = &wctx; 499 cdw.write_fn = core_vn_write; 500 cdw.extend_fn = core_vn_extend; 501 502 if (p->p_sysent->sv_coredump != NULL) { 503 error = p->p_sysent->sv_coredump(td, &cdw, limit, 0); 504 } else { 505 error = ENOSYS; 506 } 507 508 if (locked) { 509 lf.l_type = F_UNLCK; 510 VOP_ADVLOCK(vp, (caddr_t)p, F_UNLCK, &lf, F_FLOCK); 511 } 512 vn_rangelock_unlock(vp, rl_cookie); 513 514 /* 515 * Notify the userland helper that a process triggered a core dump. 516 * This allows the helper to run an automated debugging session. 517 */ 518 if (error != 0 || coredump_devctl == 0) 519 goto out; 520 sb = sbuf_new_auto(); 521 if (vn_fullpath_global(p->p_textvp, &fullpath, &freepath) != 0) 522 goto out2; 523 sbuf_cat(sb, "comm=\""); 524 devctl_safe_quote_sb(sb, fullpath); 525 free(freepath, M_TEMP); 526 sbuf_cat(sb, "\" core=\""); 527 528 /* 529 * We can't lookup core file vp directly. When we're replacing a core, and 530 * other random times, we flush the name cache, so it will fail. Instead, 531 * if the path of the core is relative, add the current dir in front if it. 532 */ 533 if (name[0] != '/') { 534 fullpathsize = MAXPATHLEN; 535 freepath = malloc(fullpathsize, M_TEMP, M_WAITOK); 536 if (vn_getcwd(freepath, &fullpath, &fullpathsize) != 0) { 537 free(freepath, M_TEMP); 538 goto out2; 539 } 540 devctl_safe_quote_sb(sb, fullpath); 541 free(freepath, M_TEMP); 542 sbuf_putc(sb, '/'); 543 } 544 devctl_safe_quote_sb(sb, name); 545 sbuf_putc(sb, '"'); 546 547 sbuf_printf(sb, " jid=%d pid=%d ppid=%d signo=%d", 548 jid, p->p_pid, ppid, sig); 549 if (sbuf_finish(sb) == 0) 550 devctl_notify("kernel", "signal", "coredump", sbuf_data(sb)); 551 out2: 552 sbuf_delete(sb); 553 out: 554 error1 = vn_close(vp, FWRITE, cred, td); 555 if (error == 0) 556 error = error1; 557 #ifdef AUDIT 558 audit_proc_coredump(td, name, error); 559 #endif 560 free(name, M_TEMP); 561 return (error); 562 } 563