1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 /* 28 * Copyright 2012 DEY Storage Systems, Inc. All rights reserved. 29 * Copyright 2018 Joyent, Inc. 30 */ 31 32 #include <sys/types.h> 33 #include <sys/param.h> 34 #include <sys/thread.h> 35 #include <sys/sysmacros.h> 36 #include <sys/signal.h> 37 #include <sys/cred.h> 38 #include <sys/priv.h> 39 #include <sys/user.h> 40 #include <sys/file.h> 41 #include <sys/errno.h> 42 #include <sys/vnode.h> 43 #include <sys/mode.h> 44 #include <sys/vfs.h> 45 #include <sys/mman.h> 46 #include <sys/kmem.h> 47 #include <sys/proc.h> 48 #include <sys/pathname.h> 49 #include <sys/cmn_err.h> 50 #include <sys/systm.h> 51 #include <sys/elf.h> 52 #include <sys/vmsystm.h> 53 #include <sys/debug.h> 54 #include <sys/procfs.h> 55 #include <sys/regset.h> 56 #include <sys/auxv.h> 57 #include <sys/exec.h> 58 #include <sys/prsystm.h> 59 #include <sys/utsname.h> 60 #include <sys/zone.h> 61 #include <vm/as.h> 62 #include <vm/rm.h> 63 #include <sys/modctl.h> 64 #include <sys/systeminfo.h> 65 #include <sys/machelf.h> 66 #include <sys/sunddi.h> 67 #include "elf_impl.h" 68 #if defined(__i386) || defined(__i386_COMPAT) 69 #include <sys/sysi86.h> 70 #endif 71 72 void 73 setup_note_header(Phdr *v, proc_t *p) 74 { 75 int nlwp = p->p_lwpcnt; 76 int nzomb = p->p_zombcnt; 77 int nfd; 78 size_t size; 79 prcred_t *pcrp; 80 uf_info_t *fip; 81 uf_entry_t *ufp; 82 int fd; 83 84 fip = P_FINFO(p); 85 nfd = 0; 86 mutex_enter(&fip->fi_lock); 87 for (fd = 0; fd < fip->fi_nfiles; fd++) { 88 UF_ENTER(ufp, fip, fd); 89 if ((ufp->uf_file != NULL) && (ufp->uf_file->f_count > 0)) 90 nfd++; 91 UF_EXIT(ufp); 92 } 93 mutex_exit(&fip->fi_lock); 94 95 v[0].p_type = PT_NOTE; 96 v[0].p_flags = PF_R; 97 v[0].p_filesz = (sizeof (Note) * (10 + 3 * nlwp + nzomb + nfd)) 98 + roundup(sizeof (psinfo_t), sizeof (Word)) 99 + roundup(sizeof (pstatus_t), sizeof (Word)) 100 + roundup(prgetprivsize(), sizeof (Word)) 101 + roundup(priv_get_implinfo_size(), sizeof (Word)) 102 + roundup(strlen(platform) + 1, sizeof (Word)) 103 + roundup(strlen(p->p_zone->zone_name) + 1, sizeof (Word)) 104 + roundup(__KERN_NAUXV_IMPL * sizeof (aux_entry_t), sizeof (Word)) 105 + roundup(sizeof (utsname), sizeof (Word)) 106 + roundup(sizeof (core_content_t), sizeof (Word)) 107 + roundup(sizeof (prsecflags_t), sizeof (Word)) 108 + (nlwp + nzomb) * roundup(sizeof (lwpsinfo_t), sizeof (Word)) 109 + nlwp * roundup(sizeof (lwpstatus_t), sizeof (Word)) 110 + nlwp * roundup(sizeof (prlwpname_t), sizeof (Word)) 111 + nfd * roundup(sizeof (prfdinfo_t), sizeof (Word)); 112 113 if (curproc->p_agenttp != NULL) { 114 v[0].p_filesz += sizeof (Note) + 115 roundup(sizeof (psinfo_t), sizeof (Word)); 116 } 117 118 size = sizeof (prcred_t) + sizeof (gid_t) * (ngroups_max - 1); 119 pcrp = kmem_alloc(size, KM_SLEEP); 120 prgetcred(p, pcrp); 121 if (pcrp->pr_ngroups != 0) { 122 v[0].p_filesz += sizeof (Note) + roundup(sizeof (prcred_t) + 123 sizeof (gid_t) * (pcrp->pr_ngroups - 1), sizeof (Word)); 124 } else { 125 v[0].p_filesz += sizeof (Note) + 126 roundup(sizeof (prcred_t), sizeof (Word)); 127 } 128 kmem_free(pcrp, size); 129 130 131 #if defined(__i386) || defined(__i386_COMPAT) 132 mutex_enter(&p->p_ldtlock); 133 size = prnldt(p) * sizeof (struct ssd); 134 mutex_exit(&p->p_ldtlock); 135 if (size != 0) 136 v[0].p_filesz += sizeof (Note) + roundup(size, sizeof (Word)); 137 #endif /* __i386 || __i386_COMPAT */ 138 139 if ((size = prhasx(p)? prgetprxregsize(p) : 0) != 0) 140 v[0].p_filesz += nlwp * sizeof (Note) 141 + nlwp * roundup(size, sizeof (Word)); 142 143 #if defined(__sparc) 144 /* 145 * Figure out the number and sizes of register windows. 146 */ 147 { 148 kthread_t *t = p->p_tlist; 149 do { 150 if ((size = prnwindows(ttolwp(t))) != 0) { 151 size = sizeof (gwindows_t) - 152 (SPARC_MAXREGWINDOW - size) * 153 sizeof (struct rwindow); 154 v[0].p_filesz += sizeof (Note) + 155 roundup(size, sizeof (Word)); 156 } 157 } while ((t = t->t_forw) != p->p_tlist); 158 } 159 /* 160 * Space for the Ancillary State Registers. 161 */ 162 if (p->p_model == DATAMODEL_LP64) 163 v[0].p_filesz += nlwp * sizeof (Note) 164 + nlwp * roundup(sizeof (asrset_t), sizeof (Word)); 165 #endif /* __sparc */ 166 } 167 168 int 169 write_elfnotes(proc_t *p, int sig, vnode_t *vp, offset_t offset, 170 rlim64_t rlimit, cred_t *credp, core_content_t content) 171 { 172 union { 173 psinfo_t psinfo; 174 pstatus_t pstatus; 175 lwpsinfo_t lwpsinfo; 176 lwpstatus_t lwpstatus; 177 #if defined(__sparc) 178 gwindows_t gwindows; 179 asrset_t asrset; 180 #endif /* __sparc */ 181 char xregs[1]; 182 aux_entry_t auxv[__KERN_NAUXV_IMPL]; 183 prcred_t pcred; 184 prpriv_t ppriv; 185 priv_impl_info_t prinfo; 186 struct utsname uts; 187 prsecflags_t psecflags; 188 } *bigwad; 189 190 size_t xregsize = prhasx(p)? prgetprxregsize(p) : 0; 191 size_t crsize = sizeof (prcred_t) + sizeof (gid_t) * (ngroups_max - 1); 192 size_t psize = prgetprivsize(); 193 size_t bigsize = MAX(psize, MAX(sizeof (*bigwad), 194 MAX(xregsize, crsize))); 195 196 priv_impl_info_t *prii; 197 198 lwpdir_t *ldp; 199 lwpent_t *lep; 200 kthread_t *t; 201 klwp_t *lwp; 202 user_t *up; 203 int i; 204 int nlwp; 205 int nzomb; 206 int error; 207 uchar_t oldsig; 208 uf_info_t *fip; 209 int fd; 210 vnode_t *vroot; 211 212 #if defined(__i386) || defined(__i386_COMPAT) 213 struct ssd *ssd; 214 size_t ssdsize; 215 #endif /* __i386 || __i386_COMPAT */ 216 217 bigsize = MAX(bigsize, priv_get_implinfo_size()); 218 219 bigwad = kmem_alloc(bigsize, KM_SLEEP); 220 221 /* 222 * The order of the elfnote entries should be same here 223 * and in the gcore(1) command. Synchronization is 224 * needed between the kernel and gcore(1). 225 */ 226 227 /* 228 * Get the psinfo, and set the wait status to indicate that a core was 229 * dumped. We have to forge this since p->p_wcode is not set yet. 230 */ 231 mutex_enter(&p->p_lock); 232 prgetpsinfo(p, &bigwad->psinfo); 233 mutex_exit(&p->p_lock); 234 bigwad->psinfo.pr_wstat = wstat(CLD_DUMPED, sig); 235 236 error = elfnote(vp, &offset, NT_PSINFO, sizeof (bigwad->psinfo), 237 (caddr_t)&bigwad->psinfo, rlimit, credp); 238 if (error) 239 goto done; 240 241 /* 242 * Modify t_whystop and lwp_cursig so it appears that the current LWP 243 * is stopped after faulting on the signal that caused the core dump. 244 * As a result, prgetstatus() will record that signal, the saved 245 * lwp_siginfo, and its signal handler in the core file status. We 246 * restore lwp_cursig in case a subsequent signal was received while 247 * dumping core. 248 */ 249 mutex_enter(&p->p_lock); 250 lwp = ttolwp(curthread); 251 252 oldsig = lwp->lwp_cursig; 253 lwp->lwp_cursig = (uchar_t)sig; 254 curthread->t_whystop = PR_FAULTED; 255 256 prgetstatus(p, &bigwad->pstatus, p->p_zone); 257 bigwad->pstatus.pr_lwp.pr_why = 0; 258 259 curthread->t_whystop = 0; 260 lwp->lwp_cursig = oldsig; 261 mutex_exit(&p->p_lock); 262 263 error = elfnote(vp, &offset, NT_PSTATUS, sizeof (bigwad->pstatus), 264 (caddr_t)&bigwad->pstatus, rlimit, credp); 265 if (error) 266 goto done; 267 268 error = elfnote(vp, &offset, NT_PLATFORM, strlen(platform) + 1, 269 platform, rlimit, credp); 270 if (error) 271 goto done; 272 273 up = PTOU(p); 274 for (i = 0; i < __KERN_NAUXV_IMPL; i++) { 275 bigwad->auxv[i].a_type = up->u_auxv[i].a_type; 276 bigwad->auxv[i].a_un.a_val = up->u_auxv[i].a_un.a_val; 277 } 278 error = elfnote(vp, &offset, NT_AUXV, sizeof (bigwad->auxv), 279 (caddr_t)bigwad->auxv, rlimit, credp); 280 if (error) 281 goto done; 282 283 bcopy(&utsname, &bigwad->uts, sizeof (struct utsname)); 284 if (!INGLOBALZONE(p)) { 285 bcopy(p->p_zone->zone_nodename, &bigwad->uts.nodename, 286 _SYS_NMLN); 287 } 288 error = elfnote(vp, &offset, NT_UTSNAME, sizeof (struct utsname), 289 (caddr_t)&bigwad->uts, rlimit, credp); 290 if (error) 291 goto done; 292 293 prgetsecflags(p, &bigwad->psecflags); 294 error = elfnote(vp, &offset, NT_SECFLAGS, sizeof (prsecflags_t), 295 (caddr_t)&bigwad->psecflags, rlimit, credp); 296 if (error) 297 goto done; 298 299 prgetcred(p, &bigwad->pcred); 300 301 if (bigwad->pcred.pr_ngroups != 0) { 302 crsize = sizeof (prcred_t) + 303 sizeof (gid_t) * (bigwad->pcred.pr_ngroups - 1); 304 } else 305 crsize = sizeof (prcred_t); 306 307 error = elfnote(vp, &offset, NT_PRCRED, crsize, 308 (caddr_t)&bigwad->pcred, rlimit, credp); 309 if (error) 310 goto done; 311 312 error = elfnote(vp, &offset, NT_CONTENT, sizeof (core_content_t), 313 (caddr_t)&content, rlimit, credp); 314 if (error) 315 goto done; 316 317 prgetpriv(p, &bigwad->ppriv); 318 319 error = elfnote(vp, &offset, NT_PRPRIV, psize, 320 (caddr_t)&bigwad->ppriv, rlimit, credp); 321 if (error) 322 goto done; 323 324 prii = priv_hold_implinfo(); 325 error = elfnote(vp, &offset, NT_PRPRIVINFO, priv_get_implinfo_size(), 326 (caddr_t)prii, rlimit, credp); 327 priv_release_implinfo(); 328 if (error) 329 goto done; 330 331 /* zone can't go away as long as process exists */ 332 error = elfnote(vp, &offset, NT_ZONENAME, 333 strlen(p->p_zone->zone_name) + 1, p->p_zone->zone_name, 334 rlimit, credp); 335 if (error) 336 goto done; 337 338 339 /* open file table */ 340 vroot = PTOU(p)->u_rdir; 341 if (vroot == NULL) 342 vroot = rootdir; 343 344 VN_HOLD(vroot); 345 346 fip = P_FINFO(p); 347 348 for (fd = 0; fd < fip->fi_nfiles; fd++) { 349 uf_entry_t *ufp; 350 vnode_t *fvp; 351 struct file *fp; 352 vattr_t vattr; 353 prfdinfo_t fdinfo; 354 355 bzero(&fdinfo, sizeof (fdinfo)); 356 357 mutex_enter(&fip->fi_lock); 358 UF_ENTER(ufp, fip, fd); 359 if (((fp = ufp->uf_file) == NULL) || (fp->f_count < 1)) { 360 UF_EXIT(ufp); 361 mutex_exit(&fip->fi_lock); 362 continue; 363 } 364 365 fdinfo.pr_fd = fd; 366 fdinfo.pr_fdflags = ufp->uf_flag; 367 fdinfo.pr_fileflags = fp->f_flag2; 368 fdinfo.pr_fileflags <<= 16; 369 fdinfo.pr_fileflags |= fp->f_flag; 370 if ((fdinfo.pr_fileflags & (FSEARCH | FEXEC)) == 0) 371 fdinfo.pr_fileflags += FOPEN; 372 fdinfo.pr_offset = fp->f_offset; 373 374 375 fvp = fp->f_vnode; 376 VN_HOLD(fvp); 377 UF_EXIT(ufp); 378 mutex_exit(&fip->fi_lock); 379 380 /* 381 * There are some vnodes that have no corresponding 382 * path. Its reasonable for this to fail, in which 383 * case the path will remain an empty string. 384 */ 385 (void) vnodetopath(vroot, fvp, fdinfo.pr_path, 386 sizeof (fdinfo.pr_path), credp); 387 388 if (VOP_GETATTR(fvp, &vattr, 0, credp, NULL) != 0) { 389 /* 390 * Try to write at least a subset of information 391 */ 392 fdinfo.pr_major = 0; 393 fdinfo.pr_minor = 0; 394 fdinfo.pr_ino = 0; 395 fdinfo.pr_mode = 0; 396 fdinfo.pr_uid = (uid_t)-1; 397 fdinfo.pr_gid = (gid_t)-1; 398 fdinfo.pr_rmajor = 0; 399 fdinfo.pr_rminor = 0; 400 fdinfo.pr_size = -1; 401 402 error = elfnote(vp, &offset, NT_FDINFO, 403 sizeof (fdinfo), &fdinfo, rlimit, credp); 404 VN_RELE(fvp); 405 if (error) { 406 VN_RELE(vroot); 407 goto done; 408 } 409 continue; 410 } 411 412 if (fvp->v_type == VSOCK) 413 fdinfo.pr_fileflags |= sock_getfasync(fvp); 414 415 VN_RELE(fvp); 416 417 /* 418 * This logic mirrors fstat(), which we cannot use 419 * directly, as it calls copyout(). 420 */ 421 fdinfo.pr_major = getmajor(vattr.va_fsid); 422 fdinfo.pr_minor = getminor(vattr.va_fsid); 423 fdinfo.pr_ino = (ino64_t)vattr.va_nodeid; 424 fdinfo.pr_mode = VTTOIF(vattr.va_type) | vattr.va_mode; 425 fdinfo.pr_uid = vattr.va_uid; 426 fdinfo.pr_gid = vattr.va_gid; 427 fdinfo.pr_rmajor = getmajor(vattr.va_rdev); 428 fdinfo.pr_rminor = getminor(vattr.va_rdev); 429 fdinfo.pr_size = (off64_t)vattr.va_size; 430 431 error = elfnote(vp, &offset, NT_FDINFO, 432 sizeof (fdinfo), &fdinfo, rlimit, credp); 433 if (error) { 434 VN_RELE(vroot); 435 goto done; 436 } 437 } 438 439 VN_RELE(vroot); 440 441 #if defined(__i386) || defined(__i386_COMPAT) 442 mutex_enter(&p->p_ldtlock); 443 ssdsize = prnldt(p) * sizeof (struct ssd); 444 if (ssdsize != 0) { 445 ssd = kmem_alloc(ssdsize, KM_SLEEP); 446 prgetldt(p, ssd); 447 error = elfnote(vp, &offset, NT_LDT, ssdsize, 448 (caddr_t)ssd, rlimit, credp); 449 kmem_free(ssd, ssdsize); 450 } 451 mutex_exit(&p->p_ldtlock); 452 if (error) 453 goto done; 454 #endif /* __i386 || defined(__i386_COMPAT) */ 455 456 nlwp = p->p_lwpcnt; 457 nzomb = p->p_zombcnt; 458 /* for each entry in the lwp directory ... */ 459 for (ldp = p->p_lwpdir; nlwp + nzomb != 0; ldp++) { 460 prlwpname_t name = { 0, }; 461 462 if ((lep = ldp->ld_entry) == NULL) /* empty slot */ 463 continue; 464 465 if ((t = lep->le_thread) != NULL) { /* active lwp */ 466 ASSERT(nlwp != 0); 467 nlwp--; 468 lwp = ttolwp(t); 469 mutex_enter(&p->p_lock); 470 prgetlwpsinfo(t, &bigwad->lwpsinfo); 471 if (t->t_name != NULL) { 472 (void) strlcpy(name.pr_lwpname, t->t_name, 473 sizeof (name.pr_lwpname)); 474 } 475 mutex_exit(&p->p_lock); 476 } else { /* zombie lwp */ 477 ASSERT(nzomb != 0); 478 nzomb--; 479 bzero(&bigwad->lwpsinfo, sizeof (bigwad->lwpsinfo)); 480 bigwad->lwpsinfo.pr_lwpid = lep->le_lwpid; 481 bigwad->lwpsinfo.pr_state = SZOMB; 482 bigwad->lwpsinfo.pr_sname = 'Z'; 483 bigwad->lwpsinfo.pr_start.tv_sec = lep->le_start; 484 } 485 486 name.pr_lwpid = bigwad->lwpsinfo.pr_lwpid; 487 488 error = elfnote(vp, &offset, NT_LWPSINFO, 489 sizeof (bigwad->lwpsinfo), (caddr_t)&bigwad->lwpsinfo, 490 rlimit, credp); 491 if (error) 492 goto done; 493 494 if (t == NULL) /* nothing more to do for a zombie */ 495 continue; 496 497 mutex_enter(&p->p_lock); 498 if (t == curthread) { 499 /* 500 * Modify t_whystop and lwp_cursig so it appears that 501 * the current LWP is stopped after faulting on the 502 * signal that caused the core dump. As a result, 503 * prgetlwpstatus() will record that signal, the saved 504 * lwp_siginfo, and its signal handler in the core file 505 * status. We restore lwp_cursig in case a subsequent 506 * signal was received while dumping core. 507 */ 508 oldsig = lwp->lwp_cursig; 509 lwp->lwp_cursig = (uchar_t)sig; 510 t->t_whystop = PR_FAULTED; 511 512 prgetlwpstatus(t, &bigwad->lwpstatus, p->p_zone); 513 bigwad->lwpstatus.pr_why = 0; 514 515 t->t_whystop = 0; 516 lwp->lwp_cursig = oldsig; 517 } else { 518 prgetlwpstatus(t, &bigwad->lwpstatus, p->p_zone); 519 } 520 mutex_exit(&p->p_lock); 521 error = elfnote(vp, &offset, NT_LWPSTATUS, 522 sizeof (bigwad->lwpstatus), (caddr_t)&bigwad->lwpstatus, 523 rlimit, credp); 524 if (error) 525 goto done; 526 527 if ((error = elfnote(vp, &offset, NT_LWPNAME, sizeof (name), 528 (caddr_t)&name, rlimit, credp)) != 0) 529 goto done; 530 531 532 #if defined(__sparc) 533 /* 534 * Unspilled SPARC register windows. 535 */ 536 { 537 size_t size = prnwindows(lwp); 538 539 if (size != 0) { 540 size = sizeof (gwindows_t) - 541 (SPARC_MAXREGWINDOW - size) * 542 sizeof (struct rwindow); 543 prgetwindows(lwp, &bigwad->gwindows); 544 error = elfnote(vp, &offset, NT_GWINDOWS, 545 size, (caddr_t)&bigwad->gwindows, 546 rlimit, credp); 547 if (error) 548 goto done; 549 } 550 } 551 /* 552 * Ancillary State Registers. 553 */ 554 if (p->p_model == DATAMODEL_LP64) { 555 prgetasregs(lwp, bigwad->asrset); 556 error = elfnote(vp, &offset, NT_ASRS, 557 sizeof (asrset_t), (caddr_t)bigwad->asrset, 558 rlimit, credp); 559 if (error) 560 goto done; 561 } 562 #endif /* __sparc */ 563 564 if (xregsize) { 565 prgetprxregs(lwp, bigwad->xregs); 566 error = elfnote(vp, &offset, NT_PRXREG, 567 xregsize, bigwad->xregs, rlimit, credp); 568 if (error) 569 goto done; 570 } 571 572 if (t->t_lwp->lwp_spymaster != NULL) { 573 void *psaddr = t->t_lwp->lwp_spymaster; 574 #ifdef _ELF32_COMPAT 575 /* 576 * On a 64-bit kernel with 32-bit ELF compatibility, 577 * this file is compiled into two different objects: 578 * one is compiled normally, and the other is compiled 579 * with _ELF32_COMPAT set -- and therefore with a 580 * psinfo_t defined to be a psinfo32_t. However, the 581 * psinfo_t denoting our spymaster is always of the 582 * native type; if we are in the _ELF32_COMPAT case, 583 * we need to explicitly convert it. 584 */ 585 if (p->p_model == DATAMODEL_ILP32) { 586 psinfo_kto32(psaddr, &bigwad->psinfo); 587 psaddr = &bigwad->psinfo; 588 } 589 #endif 590 591 error = elfnote(vp, &offset, NT_SPYMASTER, 592 sizeof (psinfo_t), psaddr, rlimit, credp); 593 if (error) 594 goto done; 595 } 596 } 597 ASSERT(nlwp == 0); 598 599 done: 600 kmem_free(bigwad, bigsize); 601 return (error); 602 } 603