1 /* $OpenBSD: exec_elf.c,v 1.156 2020/12/07 16:55:28 mpi Exp $ */ 2 3 /* 4 * Copyright (c) 1996 Per Fogelstrom 5 * All rights reserved. 6 * 7 * Copyright (c) 1994 Christos Zoulas 8 * All rights reserved. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 3. The name of the author may not be used to endorse or promote products 19 * derived from this software without specific prior written permission 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 22 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 23 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 24 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 26 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 30 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 * 32 */ 33 34 /* 35 * Copyright (c) 2001 Wasabi Systems, Inc. 36 * All rights reserved. 37 * 38 * Written by Jason R. Thorpe for Wasabi Systems, Inc. 39 * 40 * Redistribution and use in source and binary forms, with or without 41 * modification, are permitted provided that the following conditions 42 * are met: 43 * 1. Redistributions of source code must retain the above copyright 44 * notice, this list of conditions and the following disclaimer. 45 * 2. Redistributions in binary form must reproduce the above copyright 46 * notice, this list of conditions and the following disclaimer in the 47 * documentation and/or other materials provided with the distribution. 48 * 3. All advertising materials mentioning features or use of this software 49 * must display the following acknowledgement: 50 * This product includes software developed for the NetBSD Project by 51 * Wasabi Systems, Inc. 52 * 4. The name of Wasabi Systems, Inc. may not be used to endorse 53 * or promote products derived from this software without specific prior 54 * written permission. 55 * 56 * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND 57 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 58 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 59 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC 60 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 61 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 62 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 63 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 64 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 65 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 66 * POSSIBILITY OF SUCH DAMAGE. 67 */ 68 69 #include <sys/param.h> 70 #include <sys/systm.h> 71 #include <sys/kernel.h> 72 #include <sys/proc.h> 73 #include <sys/malloc.h> 74 #include <sys/pool.h> 75 #include <sys/mount.h> 76 #include <sys/namei.h> 77 #include <sys/vnode.h> 78 #include <sys/core.h> 79 #include <sys/syslog.h> 80 #include <sys/exec.h> 81 #include <sys/exec_elf.h> 82 #include <sys/fcntl.h> 83 #include <sys/ptrace.h> 84 #include <sys/syscall.h> 85 #include <sys/signalvar.h> 86 #include <sys/stat.h> 87 #include <sys/pledge.h> 88 #include <sys/smr.h> 89 90 #include <sys/mman.h> 91 92 #include <uvm/uvm_extern.h> 93 94 #include <machine/reg.h> 95 #include <machine/exec.h> 96 97 int elf_load_file(struct proc *, char *, struct exec_package *, 98 struct elf_args *); 99 int elf_check_header(Elf_Ehdr *); 100 int elf_read_from(struct proc *, struct vnode *, u_long, void *, int); 101 void elf_load_psection(struct exec_vmcmd_set *, struct vnode *, 102 Elf_Phdr *, Elf_Addr *, Elf_Addr *, int *, int); 103 int coredump_elf(struct proc *, void *); 104 void *elf_copyargs(struct exec_package *, struct ps_strings *, void *, 105 void *); 106 int exec_elf_fixup(struct proc *, struct exec_package *); 107 int elf_os_pt_note_name(Elf_Note *); 108 int elf_os_pt_note(struct proc *, struct exec_package *, Elf_Ehdr *, int *); 109 110 extern char sigcode[], esigcode[], sigcoderet[]; 111 #ifdef SYSCALL_DEBUG 112 extern char *syscallnames[]; 113 #endif 114 115 /* round up and down to page boundaries. */ 116 #define ELF_ROUND(a, b) (((a) + (b) - 1) & ~((b) - 1)) 117 #define ELF_TRUNC(a, b) ((a) & ~((b) - 1)) 118 119 /* 120 * We limit the number of program headers to 32, this should 121 * be a reasonable limit for ELF, the most we have seen so far is 12 122 */ 123 #define ELF_MAX_VALID_PHDR 32 124 125 /* 126 * How many entries are in the AuxInfo array we pass to the process? 127 */ 128 #define ELF_AUX_ENTRIES 9 129 130 /* 131 * This is the OpenBSD ELF emul 132 */ 133 struct emul emul_elf = { 134 "native", 135 NULL, 136 SYS_syscall, 137 SYS_MAXSYSCALL, 138 sysent, 139 #ifdef SYSCALL_DEBUG 140 syscallnames, 141 #else 142 NULL, 143 #endif 144 (sizeof(AuxInfo) * ELF_AUX_ENTRIES / sizeof(char *)), 145 elf_copyargs, 146 setregs, 147 exec_elf_fixup, 148 coredump_elf, 149 sigcode, 150 esigcode, 151 sigcoderet 152 }; 153 154 #define ELF_NOTE_NAME_OPENBSD 0x01 155 #define ELF_NOTE_NAME_GO 0x02 156 157 struct elf_note_name { 158 char *name; 159 int id; 160 } elf_note_names[] = { 161 { "OpenBSD", ELF_NOTE_NAME_OPENBSD }, 162 { "Go", ELF_NOTE_NAME_GO } 163 }; 164 165 #define ELFROUNDSIZE sizeof(Elf_Word) 166 #define elfround(x) roundup((x), ELFROUNDSIZE) 167 168 /* 169 * Copy arguments onto the stack in the normal way, but add some 170 * space for extra information in case of dynamic binding. 171 */ 172 void * 173 elf_copyargs(struct exec_package *pack, struct ps_strings *arginfo, 174 void *stack, void *argp) 175 { 176 stack = copyargs(pack, arginfo, stack, argp); 177 if (!stack) 178 return (NULL); 179 180 /* 181 * Push space for extra arguments on the stack needed by 182 * dynamically linked binaries. 183 */ 184 if (pack->ep_emul_arg != NULL) { 185 pack->ep_emul_argp = stack; 186 stack = (char *)stack + ELF_AUX_ENTRIES * sizeof (AuxInfo); 187 } 188 return (stack); 189 } 190 191 /* 192 * Check header for validity; return 0 for ok, ENOEXEC if error 193 */ 194 int 195 elf_check_header(Elf_Ehdr *ehdr) 196 { 197 /* 198 * We need to check magic, class size, endianess, and version before 199 * we look at the rest of the Elf_Ehdr structure. These few elements 200 * are represented in a machine independent fashion. 201 */ 202 if (!IS_ELF(*ehdr) || 203 ehdr->e_ident[EI_CLASS] != ELF_TARG_CLASS || 204 ehdr->e_ident[EI_DATA] != ELF_TARG_DATA || 205 ehdr->e_ident[EI_VERSION] != ELF_TARG_VER) 206 return (ENOEXEC); 207 208 /* Now check the machine dependent header */ 209 if (ehdr->e_machine != ELF_TARG_MACH || 210 ehdr->e_version != ELF_TARG_VER) 211 return (ENOEXEC); 212 213 /* Don't allow an insane amount of sections. */ 214 if (ehdr->e_phnum > ELF_MAX_VALID_PHDR) 215 return (ENOEXEC); 216 217 return (0); 218 } 219 220 /* 221 * Load a psection at the appropriate address 222 */ 223 void 224 elf_load_psection(struct exec_vmcmd_set *vcset, struct vnode *vp, 225 Elf_Phdr *ph, Elf_Addr *addr, Elf_Addr *size, int *prot, int flags) 226 { 227 u_long msize, lsize, psize, rm, rf; 228 long diff, offset, bdiff; 229 Elf_Addr base; 230 231 /* 232 * If the user specified an address, then we load there. 233 */ 234 if (*addr != ELF_NO_ADDR) { 235 if (ph->p_align > 1) { 236 *addr = ELF_TRUNC(*addr, ph->p_align); 237 diff = ph->p_vaddr - ELF_TRUNC(ph->p_vaddr, ph->p_align); 238 /* page align vaddr */ 239 base = *addr + trunc_page(ph->p_vaddr) 240 - ELF_TRUNC(ph->p_vaddr, ph->p_align); 241 } else { 242 diff = 0; 243 base = *addr + trunc_page(ph->p_vaddr) - ph->p_vaddr; 244 } 245 } else { 246 *addr = ph->p_vaddr; 247 if (ph->p_align > 1) 248 *addr = ELF_TRUNC(*addr, ph->p_align); 249 base = trunc_page(ph->p_vaddr); 250 diff = ph->p_vaddr - *addr; 251 } 252 bdiff = ph->p_vaddr - trunc_page(ph->p_vaddr); 253 254 /* 255 * Enforce W^X and map W|X segments without X permission 256 * initially. The dynamic linker will make these read-only 257 * and add back X permission after relocation processing. 258 * Static executables with W|X segments will probably crash. 259 */ 260 *prot |= (ph->p_flags & PF_R) ? PROT_READ : 0; 261 *prot |= (ph->p_flags & PF_W) ? PROT_WRITE : 0; 262 if ((ph->p_flags & PF_W) == 0) 263 *prot |= (ph->p_flags & PF_X) ? PROT_EXEC : 0; 264 265 msize = ph->p_memsz + diff; 266 offset = ph->p_offset - bdiff; 267 lsize = ph->p_filesz + bdiff; 268 psize = round_page(lsize); 269 270 /* 271 * Because the pagedvn pager can't handle zero fill of the last 272 * data page if it's not page aligned we map the last page readvn. 273 */ 274 if (ph->p_flags & PF_W) { 275 psize = trunc_page(lsize); 276 if (psize > 0) 277 NEW_VMCMD2(vcset, vmcmd_map_pagedvn, psize, base, vp, 278 offset, *prot, flags); 279 if (psize != lsize) { 280 NEW_VMCMD2(vcset, vmcmd_map_readvn, lsize - psize, 281 base + psize, vp, offset + psize, *prot, flags); 282 } 283 } else { 284 NEW_VMCMD2(vcset, vmcmd_map_pagedvn, psize, base, vp, offset, 285 *prot, flags); 286 } 287 288 /* 289 * Check if we need to extend the size of the segment 290 */ 291 rm = round_page(*addr + ph->p_memsz + diff); 292 rf = round_page(*addr + ph->p_filesz + diff); 293 294 if (rm != rf) { 295 NEW_VMCMD2(vcset, vmcmd_map_zero, rm - rf, rf, NULLVP, 0, 296 *prot, flags); 297 } 298 *size = msize; 299 } 300 301 /* 302 * Read from vnode into buffer at offset. 303 */ 304 int 305 elf_read_from(struct proc *p, struct vnode *vp, u_long off, void *buf, 306 int size) 307 { 308 int error; 309 size_t resid; 310 311 if ((error = vn_rdwr(UIO_READ, vp, buf, size, off, UIO_SYSSPACE, 312 0, p->p_ucred, &resid, p)) != 0) 313 return error; 314 /* 315 * See if we got all of it 316 */ 317 if (resid != 0) 318 return (ENOEXEC); 319 return (0); 320 } 321 322 /* 323 * Load a file (interpreter/library) pointed to by path [stolen from 324 * coff_load_shlib()]. Made slightly generic so it might be used externally. 325 */ 326 int 327 elf_load_file(struct proc *p, char *path, struct exec_package *epp, 328 struct elf_args *ap) 329 { 330 int error, i; 331 struct nameidata nd; 332 Elf_Ehdr eh; 333 Elf_Phdr *ph = NULL; 334 u_long phsize = 0; 335 Elf_Addr addr; 336 struct vnode *vp; 337 Elf_Phdr *base_ph = NULL; 338 struct interp_ld_sec { 339 Elf_Addr vaddr; 340 u_long memsz; 341 } loadmap[ELF_MAX_VALID_PHDR]; 342 int nload, idx = 0; 343 Elf_Addr pos; 344 int file_align; 345 int loop; 346 size_t randomizequota = ELF_RANDOMIZE_LIMIT; 347 348 NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_SYSSPACE, path, p); 349 nd.ni_pledge = PLEDGE_RPATH; 350 nd.ni_unveil = UNVEIL_READ; 351 if ((error = namei(&nd)) != 0) { 352 return (error); 353 } 354 vp = nd.ni_vp; 355 if (vp->v_type != VREG) { 356 error = EACCES; 357 goto bad; 358 } 359 if ((error = VOP_GETATTR(vp, epp->ep_vap, p->p_ucred, p)) != 0) 360 goto bad; 361 if (vp->v_mount->mnt_flag & MNT_NOEXEC) { 362 error = EACCES; 363 goto bad; 364 } 365 if ((error = VOP_ACCESS(vp, VREAD, p->p_ucred, p)) != 0) 366 goto bad1; 367 if ((error = elf_read_from(p, nd.ni_vp, 0, &eh, sizeof(eh))) != 0) 368 goto bad1; 369 370 if (elf_check_header(&eh) || eh.e_type != ET_DYN) { 371 error = ENOEXEC; 372 goto bad1; 373 } 374 375 ph = mallocarray(eh.e_phnum, sizeof(Elf_Phdr), M_TEMP, M_WAITOK); 376 phsize = eh.e_phnum * sizeof(Elf_Phdr); 377 378 if ((error = elf_read_from(p, nd.ni_vp, eh.e_phoff, ph, phsize)) != 0) 379 goto bad1; 380 381 for (i = 0; i < eh.e_phnum; i++) { 382 if (ph[i].p_type == PT_LOAD) { 383 if (ph[i].p_filesz > ph[i].p_memsz || 384 ph[i].p_memsz == 0) { 385 error = EINVAL; 386 goto bad1; 387 } 388 loadmap[idx].vaddr = trunc_page(ph[i].p_vaddr); 389 loadmap[idx].memsz = round_page (ph[i].p_vaddr + 390 ph[i].p_memsz - loadmap[idx].vaddr); 391 file_align = ph[i].p_align; 392 idx++; 393 } 394 } 395 nload = idx; 396 397 /* 398 * Load the interpreter where a non-fixed mmap(NULL, ...) 399 * would (i.e. something safely out of the way). 400 */ 401 pos = uvm_map_hint(p->p_vmspace, PROT_EXEC, VM_MIN_ADDRESS, 402 VM_MAXUSER_ADDRESS); 403 pos = ELF_ROUND(pos, file_align); 404 405 loop = 0; 406 for (i = 0; i < nload;/**/) { 407 vaddr_t addr; 408 struct uvm_object *uobj; 409 off_t uoff; 410 size_t size; 411 412 #ifdef this_needs_fixing 413 if (i == 0) { 414 uobj = &vp->v_uvm.u_obj; 415 /* need to fix uoff */ 416 } else { 417 #endif 418 uobj = NULL; 419 uoff = 0; 420 #ifdef this_needs_fixing 421 } 422 #endif 423 424 addr = trunc_page(pos + loadmap[i].vaddr); 425 size = round_page(addr + loadmap[i].memsz) - addr; 426 427 /* CRAP - map_findspace does not avoid daddr+BRKSIZ */ 428 if ((addr + size > (vaddr_t)p->p_vmspace->vm_daddr) && 429 (addr < (vaddr_t)p->p_vmspace->vm_daddr + BRKSIZ)) 430 addr = round_page((vaddr_t)p->p_vmspace->vm_daddr + 431 BRKSIZ); 432 433 if (uvm_map_mquery(&p->p_vmspace->vm_map, &addr, size, 434 (i == 0 ? uoff : UVM_UNKNOWN_OFFSET), 0) != 0) { 435 if (loop == 0) { 436 loop = 1; 437 i = 0; 438 pos = 0; 439 continue; 440 } 441 error = ENOMEM; 442 goto bad1; 443 } 444 if (addr != pos + loadmap[i].vaddr) { 445 /* base changed. */ 446 pos = addr - trunc_page(loadmap[i].vaddr); 447 pos = ELF_ROUND(pos,file_align); 448 i = 0; 449 continue; 450 } 451 452 i++; 453 } 454 455 /* 456 * Load all the necessary sections 457 */ 458 for (i = 0; i < eh.e_phnum; i++) { 459 Elf_Addr size = 0; 460 int prot = 0; 461 int flags; 462 463 switch (ph[i].p_type) { 464 case PT_LOAD: 465 if (base_ph == NULL) { 466 flags = VMCMD_BASE; 467 addr = pos; 468 base_ph = &ph[i]; 469 } else { 470 flags = VMCMD_RELATIVE; 471 addr = ph[i].p_vaddr - base_ph->p_vaddr; 472 } 473 elf_load_psection(&epp->ep_vmcmds, nd.ni_vp, 474 &ph[i], &addr, &size, &prot, flags | VMCMD_SYSCALL); 475 /* If entry is within this section it must be text */ 476 if (eh.e_entry >= ph[i].p_vaddr && 477 eh.e_entry < (ph[i].p_vaddr + size)) { 478 epp->ep_entry = addr + eh.e_entry - 479 ELF_TRUNC(ph[i].p_vaddr,ph[i].p_align); 480 if (flags == VMCMD_RELATIVE) 481 epp->ep_entry += pos; 482 ap->arg_interp = pos; 483 } 484 addr += size; 485 break; 486 487 case PT_DYNAMIC: 488 case PT_PHDR: 489 case PT_NOTE: 490 break; 491 492 case PT_OPENBSD_RANDOMIZE: 493 if (ph[i].p_memsz > randomizequota) { 494 error = ENOMEM; 495 goto bad1; 496 } 497 randomizequota -= ph[i].p_memsz; 498 NEW_VMCMD(&epp->ep_vmcmds, vmcmd_randomize, 499 ph[i].p_memsz, ph[i].p_vaddr + pos, NULLVP, 0, 0); 500 break; 501 502 default: 503 break; 504 } 505 } 506 507 vn_marktext(nd.ni_vp); 508 509 bad1: 510 VOP_CLOSE(nd.ni_vp, FREAD, p->p_ucred, p); 511 bad: 512 free(ph, M_TEMP, phsize); 513 514 vput(nd.ni_vp); 515 return (error); 516 } 517 518 /* 519 * Prepare an Elf binary's exec package 520 * 521 * First, set of the various offsets/lengths in the exec package. 522 * 523 * Then, mark the text image busy (so it can be demand paged) or error out if 524 * this is not possible. Finally, set up vmcmds for the text, data, bss, and 525 * stack segments. 526 */ 527 int 528 exec_elf_makecmds(struct proc *p, struct exec_package *epp) 529 { 530 Elf_Ehdr *eh = epp->ep_hdr; 531 Elf_Phdr *ph, *pp, *base_ph = NULL; 532 Elf_Addr phdr = 0, exe_base = 0; 533 int error, i, has_phdr = 0, names = 0; 534 char *interp = NULL; 535 u_long phsize; 536 size_t randomizequota = ELF_RANDOMIZE_LIMIT; 537 538 if (epp->ep_hdrvalid < sizeof(Elf_Ehdr)) 539 return (ENOEXEC); 540 541 if (elf_check_header(eh) || 542 (eh->e_type != ET_EXEC && eh->e_type != ET_DYN)) 543 return (ENOEXEC); 544 545 /* 546 * check if vnode is in open for writing, because we want to demand- 547 * page out of it. if it is, don't do it, for various reasons. 548 */ 549 if (epp->ep_vp->v_writecount != 0) { 550 #ifdef DIAGNOSTIC 551 if (epp->ep_vp->v_flag & VTEXT) 552 panic("exec: a VTEXT vnode has writecount != 0"); 553 #endif 554 return (ETXTBSY); 555 } 556 /* 557 * Allocate space to hold all the program headers, and read them 558 * from the file 559 */ 560 ph = mallocarray(eh->e_phnum, sizeof(Elf_Phdr), M_TEMP, M_WAITOK); 561 phsize = eh->e_phnum * sizeof(Elf_Phdr); 562 563 if ((error = elf_read_from(p, epp->ep_vp, eh->e_phoff, ph, 564 phsize)) != 0) 565 goto bad; 566 567 epp->ep_tsize = ELF_NO_ADDR; 568 epp->ep_dsize = ELF_NO_ADDR; 569 570 for (i = 0, pp = ph; i < eh->e_phnum; i++, pp++) { 571 if (pp->p_type == PT_INTERP && !interp) { 572 if (pp->p_filesz < 2 || pp->p_filesz > MAXPATHLEN) 573 goto bad; 574 interp = pool_get(&namei_pool, PR_WAITOK); 575 if ((error = elf_read_from(p, epp->ep_vp, 576 pp->p_offset, interp, pp->p_filesz)) != 0) { 577 goto bad; 578 } 579 if (interp[pp->p_filesz - 1] != '\0') 580 goto bad; 581 } else if (pp->p_type == PT_LOAD) { 582 if (pp->p_filesz > pp->p_memsz || 583 pp->p_memsz == 0) { 584 error = EINVAL; 585 goto bad; 586 } 587 if (base_ph == NULL) 588 base_ph = pp; 589 } else if (pp->p_type == PT_PHDR) { 590 has_phdr = 1; 591 } 592 } 593 594 if (eh->e_type == ET_DYN) { 595 /* need phdr and load sections for PIE */ 596 if (!has_phdr || base_ph == NULL) { 597 error = EINVAL; 598 goto bad; 599 } 600 /* randomize exe_base for PIE */ 601 exe_base = uvm_map_pie(base_ph->p_align); 602 } 603 604 /* 605 * OK, we want a slightly different twist of the 606 * standard emulation package for "real" elf. 607 */ 608 epp->ep_emul = &emul_elf; 609 610 /* 611 * Verify this is an OpenBSD executable. If it's marked that way 612 * via a PT_NOTE then also check for a PT_OPENBSD_WXNEEDED segment. 613 */ 614 if ((error = elf_os_pt_note(p, epp, epp->ep_hdr, &names)) != 0) 615 goto bad; 616 if (eh->e_ident[EI_OSABI] == ELFOSABI_OPENBSD) 617 names |= ELF_NOTE_NAME_OPENBSD; 618 619 /* 620 * Load all the necessary sections 621 */ 622 for (i = 0, pp = ph; i < eh->e_phnum; i++, pp++) { 623 Elf_Addr addr, size = 0; 624 int prot = 0; 625 int flags = 0; 626 627 switch (pp->p_type) { 628 case PT_LOAD: 629 if (exe_base != 0) { 630 if (pp == base_ph) { 631 flags = VMCMD_BASE; 632 addr = exe_base; 633 } else { 634 flags = VMCMD_RELATIVE; 635 addr = pp->p_vaddr - base_ph->p_vaddr; 636 } 637 } else 638 addr = ELF_NO_ADDR; 639 640 /* Permit system calls in specific main-programs */ 641 if (names & ELF_NOTE_NAME_GO) { 642 /* go main-binaries; we await a libc future */ 643 flags |= VMCMD_SYSCALL; 644 } else if (interp == NULL) { 645 /* statics. Also block the ld.so syscall-grant */ 646 flags |= VMCMD_SYSCALL; 647 p->p_vmspace->vm_map.flags |= VM_MAP_SYSCALL_ONCE; 648 } 649 650 /* 651 * Calculates size of text and data segments 652 * by starting at first and going to end of last. 653 * 'rwx' sections are treated as data. 654 * this is correct for BSS_PLT, but may not be 655 * for DATA_PLT, is fine for TEXT_PLT. 656 */ 657 elf_load_psection(&epp->ep_vmcmds, epp->ep_vp, 658 pp, &addr, &size, &prot, flags); 659 660 /* 661 * Update exe_base in case alignment was off. 662 * For PIE, addr is relative to exe_base so 663 * adjust it (non PIE exe_base is 0 so no change). 664 */ 665 if (flags == VMCMD_BASE) 666 exe_base = addr; 667 else 668 addr += exe_base; 669 670 /* 671 * Decide whether it's text or data by looking 672 * at the protection of the section 673 */ 674 if (prot & PROT_WRITE) { 675 /* data section */ 676 if (epp->ep_dsize == ELF_NO_ADDR) { 677 epp->ep_daddr = addr; 678 epp->ep_dsize = size; 679 } else { 680 if (addr < epp->ep_daddr) { 681 epp->ep_dsize = 682 epp->ep_dsize + 683 epp->ep_daddr - 684 addr; 685 epp->ep_daddr = addr; 686 } else 687 epp->ep_dsize = addr+size - 688 epp->ep_daddr; 689 } 690 } else if (prot & PROT_EXEC) { 691 /* text section */ 692 if (epp->ep_tsize == ELF_NO_ADDR) { 693 epp->ep_taddr = addr; 694 epp->ep_tsize = size; 695 } else { 696 if (addr < epp->ep_taddr) { 697 epp->ep_tsize = 698 epp->ep_tsize + 699 epp->ep_taddr - 700 addr; 701 epp->ep_taddr = addr; 702 } else 703 epp->ep_tsize = addr+size - 704 epp->ep_taddr; 705 } 706 } 707 break; 708 709 case PT_SHLIB: 710 error = ENOEXEC; 711 goto bad; 712 713 case PT_INTERP: 714 /* Already did this one */ 715 case PT_DYNAMIC: 716 case PT_NOTE: 717 break; 718 719 case PT_PHDR: 720 /* Note address of program headers (in text segment) */ 721 phdr = pp->p_vaddr; 722 break; 723 724 case PT_OPENBSD_RANDOMIZE: 725 if (ph[i].p_memsz > randomizequota) { 726 error = ENOMEM; 727 goto bad; 728 } 729 randomizequota -= ph[i].p_memsz; 730 NEW_VMCMD(&epp->ep_vmcmds, vmcmd_randomize, 731 ph[i].p_memsz, ph[i].p_vaddr + exe_base, NULLVP, 0, 0); 732 break; 733 734 default: 735 /* 736 * Not fatal, we don't need to understand everything 737 * :-) 738 */ 739 break; 740 } 741 } 742 743 phdr += exe_base; 744 745 /* 746 * Strangely some linux programs may have all load sections marked 747 * writeable, in this case, textsize is not -1, but rather 0; 748 */ 749 if (epp->ep_tsize == ELF_NO_ADDR) 750 epp->ep_tsize = 0; 751 /* 752 * Another possibility is that it has all load sections marked 753 * read-only. Fake a zero-sized data segment right after the 754 * text segment. 755 */ 756 if (epp->ep_dsize == ELF_NO_ADDR) { 757 epp->ep_daddr = round_page(epp->ep_taddr + epp->ep_tsize); 758 epp->ep_dsize = 0; 759 } 760 761 epp->ep_interp = interp; 762 epp->ep_entry = eh->e_entry + exe_base; 763 764 /* 765 * Check if we found a dynamically linked binary and arrange to load 766 * its interpreter when the exec file is released. 767 */ 768 if (interp || eh->e_type == ET_DYN) { 769 struct elf_args *ap; 770 771 ap = malloc(sizeof(*ap), M_TEMP, M_WAITOK); 772 773 ap->arg_phaddr = phdr; 774 ap->arg_phentsize = eh->e_phentsize; 775 ap->arg_phnum = eh->e_phnum; 776 ap->arg_entry = eh->e_entry + exe_base; 777 ap->arg_interp = exe_base; 778 779 epp->ep_emul_arg = ap; 780 epp->ep_emul_argsize = sizeof *ap; 781 } 782 783 free(ph, M_TEMP, phsize); 784 vn_marktext(epp->ep_vp); 785 return (exec_setup_stack(p, epp)); 786 787 bad: 788 if (interp) 789 pool_put(&namei_pool, interp); 790 free(ph, M_TEMP, phsize); 791 kill_vmcmds(&epp->ep_vmcmds); 792 if (error == 0) 793 return (ENOEXEC); 794 return (error); 795 } 796 797 /* 798 * Phase II of load. It is now safe to load the interpreter. Info collected 799 * when loading the program is available for setup of the interpreter. 800 */ 801 int 802 exec_elf_fixup(struct proc *p, struct exec_package *epp) 803 { 804 char *interp; 805 int error = 0; 806 struct elf_args *ap; 807 AuxInfo ai[ELF_AUX_ENTRIES], *a; 808 809 if (epp->ep_emul_arg == NULL) { 810 return (0); 811 } 812 813 interp = epp->ep_interp; 814 ap = epp->ep_emul_arg; 815 816 if (interp && 817 (error = elf_load_file(p, interp, epp, ap)) != 0) { 818 free(ap, M_TEMP, epp->ep_emul_argsize); 819 pool_put(&namei_pool, interp); 820 kill_vmcmds(&epp->ep_vmcmds); 821 return (error); 822 } 823 /* 824 * We have to do this ourselves... 825 */ 826 error = exec_process_vmcmds(p, epp); 827 828 /* 829 * Push extra arguments on the stack needed by dynamically 830 * linked binaries 831 */ 832 if (error == 0) { 833 memset(&ai, 0, sizeof ai); 834 a = ai; 835 836 a->au_id = AUX_phdr; 837 a->au_v = ap->arg_phaddr; 838 a++; 839 840 a->au_id = AUX_phent; 841 a->au_v = ap->arg_phentsize; 842 a++; 843 844 a->au_id = AUX_phnum; 845 a->au_v = ap->arg_phnum; 846 a++; 847 848 a->au_id = AUX_pagesz; 849 a->au_v = PAGE_SIZE; 850 a++; 851 852 a->au_id = AUX_base; 853 a->au_v = ap->arg_interp; 854 a++; 855 856 a->au_id = AUX_flags; 857 a->au_v = 0; 858 a++; 859 860 a->au_id = AUX_entry; 861 a->au_v = ap->arg_entry; 862 a++; 863 864 a->au_id = AUX_openbsd_timekeep; 865 a->au_v = p->p_p->ps_timekeep; 866 a++; 867 868 a->au_id = AUX_null; 869 a->au_v = 0; 870 a++; 871 872 error = copyout(ai, epp->ep_emul_argp, sizeof ai); 873 } 874 free(ap, M_TEMP, epp->ep_emul_argsize); 875 if (interp) 876 pool_put(&namei_pool, interp); 877 return (error); 878 } 879 880 int 881 elf_os_pt_note_name(Elf_Note *np) 882 { 883 int i, j; 884 885 for (i = 0; i < nitems(elf_note_names); i++) { 886 size_t namlen = strlen(elf_note_names[i].name); 887 if (np->namesz < namlen) 888 continue; 889 /* verify name padding (after the NUL) is NUL */ 890 for (j = namlen + 1; j < elfround(np->namesz); j++) 891 if (((char *)(np + 1))[j] != '\0') 892 continue; 893 /* verify desc padding is NUL */ 894 for (j = np->descsz; j < elfround(np->descsz); j++) 895 if (((char *)(np + 1))[j] != '\0') 896 continue; 897 if (strcmp((char *)(np + 1), elf_note_names[i].name) == 0) 898 return elf_note_names[i].id; 899 } 900 return (0); 901 } 902 903 int 904 elf_os_pt_note(struct proc *p, struct exec_package *epp, Elf_Ehdr *eh, int *namesp) 905 { 906 Elf_Phdr *hph, *ph; 907 Elf_Note *np = NULL; 908 size_t phsize, offset, pfilesz = 0, total; 909 int error, names = 0; 910 911 hph = mallocarray(eh->e_phnum, sizeof(Elf_Phdr), M_TEMP, M_WAITOK); 912 phsize = eh->e_phnum * sizeof(Elf_Phdr); 913 if ((error = elf_read_from(p, epp->ep_vp, eh->e_phoff, 914 hph, phsize)) != 0) 915 goto out1; 916 917 for (ph = hph; ph < &hph[eh->e_phnum]; ph++) { 918 if (ph->p_type == PT_OPENBSD_WXNEEDED) { 919 epp->ep_flags |= EXEC_WXNEEDED; 920 continue; 921 } 922 923 if (ph->p_type != PT_NOTE || ph->p_filesz > 1024) 924 continue; 925 926 if (np && ph->p_filesz != pfilesz) { 927 free(np, M_TEMP, pfilesz); 928 np = NULL; 929 } 930 if (!np) 931 np = malloc(ph->p_filesz, M_TEMP, M_WAITOK); 932 pfilesz = ph->p_filesz; 933 if ((error = elf_read_from(p, epp->ep_vp, ph->p_offset, 934 np, ph->p_filesz)) != 0) 935 goto out2; 936 937 for (offset = 0; offset < ph->p_filesz; offset += total) { 938 Elf_Note *np2 = (Elf_Note *)((char *)np + offset); 939 940 if (offset + sizeof(Elf_Note) > ph->p_filesz) 941 break; 942 total = sizeof(Elf_Note) + elfround(np2->namesz) + 943 elfround(np2->descsz); 944 if (offset + total > ph->p_filesz) 945 break; 946 names |= elf_os_pt_note_name(np2); 947 } 948 } 949 950 out2: 951 free(np, M_TEMP, pfilesz); 952 out1: 953 free(hph, M_TEMP, phsize); 954 *namesp = names; 955 return ((names & ELF_NOTE_NAME_OPENBSD) ? 0 : ENOEXEC); 956 } 957 958 /* 959 * Start of routines related to dumping core 960 */ 961 962 #ifdef SMALL_KERNEL 963 int 964 coredump_elf(struct proc *p, void *cookie) 965 { 966 return EPERM; 967 } 968 #else /* !SMALL_KERNEL */ 969 970 struct writesegs_state { 971 off_t notestart; 972 off_t secstart; 973 off_t secoff; 974 struct proc *p; 975 void *iocookie; 976 Elf_Phdr *psections; 977 size_t psectionslen; 978 size_t notesize; 979 int npsections; 980 }; 981 982 uvm_coredump_setup_cb coredump_setup_elf; 983 uvm_coredump_walk_cb coredump_walk_elf; 984 985 int coredump_notes_elf(struct proc *, void *, size_t *); 986 int coredump_note_elf(struct proc *, void *, size_t *); 987 int coredump_writenote_elf(struct proc *, void *, Elf_Note *, 988 const char *, void *); 989 990 int 991 coredump_elf(struct proc *p, void *cookie) 992 { 993 #ifdef DIAGNOSTIC 994 off_t offset; 995 #endif 996 struct writesegs_state ws; 997 size_t notesize; 998 int error, i; 999 1000 ws.p = p; 1001 ws.iocookie = cookie; 1002 ws.psections = NULL; 1003 1004 /* 1005 * Walk the map to get all the segment offsets and lengths, 1006 * write out the ELF header. 1007 */ 1008 error = uvm_coredump_walkmap(p, coredump_setup_elf, 1009 coredump_walk_elf, &ws); 1010 if (error) 1011 goto out; 1012 1013 error = coredump_write(cookie, UIO_SYSSPACE, ws.psections, 1014 ws.psectionslen); 1015 if (error) 1016 goto out; 1017 1018 /* Write out the notes. */ 1019 error = coredump_notes_elf(p, cookie, ¬esize); 1020 if (error) 1021 goto out; 1022 1023 #ifdef DIAGNOSTIC 1024 if (notesize != ws.notesize) 1025 panic("coredump: notesize changed: %zu != %zu", 1026 ws.notesize, notesize); 1027 offset = ws.notestart + notesize; 1028 if (offset != ws.secstart) 1029 panic("coredump: offset %lld != secstart %lld", 1030 (long long) offset, (long long) ws.secstart); 1031 #endif 1032 1033 /* Pass 3: finally, write the sections themselves. */ 1034 for (i = 0; i < ws.npsections - 1; i++) { 1035 Elf_Phdr *pent = &ws.psections[i]; 1036 if (pent->p_filesz == 0) 1037 continue; 1038 1039 #ifdef DIAGNOSTIC 1040 if (offset != pent->p_offset) 1041 panic("coredump: offset %lld != p_offset[%d] %lld", 1042 (long long) offset, i, 1043 (long long) pent->p_filesz); 1044 #endif 1045 1046 error = coredump_write(cookie, UIO_USERSPACE, 1047 (void *)(vaddr_t)pent->p_vaddr, pent->p_filesz); 1048 if (error) 1049 goto out; 1050 1051 coredump_unmap(cookie, (vaddr_t)pent->p_vaddr, 1052 (vaddr_t)pent->p_vaddr + pent->p_filesz); 1053 1054 #ifdef DIAGNOSTIC 1055 offset += ws.psections[i].p_filesz; 1056 #endif 1057 } 1058 1059 out: 1060 free(ws.psections, M_TEMP, ws.psectionslen); 1061 return (error); 1062 } 1063 1064 1065 /* 1066 * Normally we lay out core files like this: 1067 * [ELF Header] [Program headers] [Notes] [data for PT_LOAD segments] 1068 * 1069 * However, if there's >= 65535 segments then it overflows the field 1070 * in the ELF header, so the standard specifies putting a magic 1071 * number there and saving the real count in the .sh_info field of 1072 * the first *section* header...which requires generating a section 1073 * header. To avoid confusing tools, we include an .shstrtab section 1074 * as well so all the indexes look valid. So in this case we lay 1075 * out the core file like this: 1076 * [ELF Header] [Section Headers] [.shstrtab] [Program headers] \ 1077 * [Notes] [data for PT_LOAD segments] 1078 * 1079 * The 'shstrtab' structure below is data for the second of the two 1080 * section headers, plus the .shstrtab itself, in one const buffer. 1081 */ 1082 static const struct { 1083 Elf_Shdr shdr; 1084 char shstrtab[sizeof(ELF_SHSTRTAB) + 1]; 1085 } shstrtab = { 1086 .shdr = { 1087 .sh_name = 1, /* offset in .shstrtab below */ 1088 .sh_type = SHT_STRTAB, 1089 .sh_offset = sizeof(Elf_Ehdr) + 2*sizeof(Elf_Shdr), 1090 .sh_size = sizeof(ELF_SHSTRTAB) + 1, 1091 .sh_addralign = 1, 1092 }, 1093 .shstrtab = "\0" ELF_SHSTRTAB, 1094 }; 1095 1096 int 1097 coredump_setup_elf(int segment_count, void *cookie) 1098 { 1099 Elf_Ehdr ehdr; 1100 struct writesegs_state *ws = cookie; 1101 Elf_Phdr *note; 1102 int error; 1103 1104 /* Get the count of segments, plus one for the PT_NOTE */ 1105 ws->npsections = segment_count + 1; 1106 1107 /* Get the size of the notes. */ 1108 error = coredump_notes_elf(ws->p, NULL, &ws->notesize); 1109 if (error) 1110 return error; 1111 1112 /* Setup the ELF header */ 1113 memset(&ehdr, 0, sizeof(ehdr)); 1114 memcpy(ehdr.e_ident, ELFMAG, SELFMAG); 1115 ehdr.e_ident[EI_CLASS] = ELF_TARG_CLASS; 1116 ehdr.e_ident[EI_DATA] = ELF_TARG_DATA; 1117 ehdr.e_ident[EI_VERSION] = EV_CURRENT; 1118 /* XXX Should be the OSABI/ABI version of the executable. */ 1119 ehdr.e_ident[EI_OSABI] = ELFOSABI_SYSV; 1120 ehdr.e_ident[EI_ABIVERSION] = 0; 1121 ehdr.e_type = ET_CORE; 1122 /* XXX This should be the e_machine of the executable. */ 1123 ehdr.e_machine = ELF_TARG_MACH; 1124 ehdr.e_version = EV_CURRENT; 1125 ehdr.e_entry = 0; 1126 ehdr.e_flags = 0; 1127 ehdr.e_ehsize = sizeof(ehdr); 1128 ehdr.e_phentsize = sizeof(Elf_Phdr); 1129 1130 if (ws->npsections < PN_XNUM) { 1131 ehdr.e_phoff = sizeof(ehdr); 1132 ehdr.e_shoff = 0; 1133 ehdr.e_phnum = ws->npsections; 1134 ehdr.e_shentsize = 0; 1135 ehdr.e_shnum = 0; 1136 ehdr.e_shstrndx = 0; 1137 } else { 1138 /* too many segments, use extension setup */ 1139 ehdr.e_shoff = sizeof(ehdr); 1140 ehdr.e_phnum = PN_XNUM; 1141 ehdr.e_shentsize = sizeof(Elf_Shdr); 1142 ehdr.e_shnum = 2; 1143 ehdr.e_shstrndx = 1; 1144 ehdr.e_phoff = shstrtab.shdr.sh_offset + shstrtab.shdr.sh_size; 1145 } 1146 1147 /* Write out the ELF header. */ 1148 error = coredump_write(ws->iocookie, UIO_SYSSPACE, &ehdr, sizeof(ehdr)); 1149 if (error) 1150 return error; 1151 1152 /* 1153 * If an section header is needed to store extension info, write 1154 * it out after the ELF header and before the program header. 1155 */ 1156 if (ehdr.e_shnum != 0) { 1157 Elf_Shdr shdr = { .sh_info = ws->npsections }; 1158 error = coredump_write(ws->iocookie, UIO_SYSSPACE, &shdr, 1159 sizeof shdr); 1160 if (error) 1161 return error; 1162 error = coredump_write(ws->iocookie, UIO_SYSSPACE, &shstrtab, 1163 sizeof(shstrtab.shdr) + sizeof(shstrtab.shstrtab)); 1164 if (error) 1165 return error; 1166 } 1167 1168 /* 1169 * Allocate the segment header array and setup to collect 1170 * the section sizes and offsets 1171 */ 1172 ws->psections = mallocarray(ws->npsections, sizeof(Elf_Phdr), 1173 M_TEMP, M_WAITOK|M_CANFAIL|M_ZERO); 1174 if (ws->psections == NULL) 1175 return ENOMEM; 1176 ws->psectionslen = ws->npsections * sizeof(Elf_Phdr); 1177 1178 ws->notestart = ehdr.e_phoff + ws->psectionslen; 1179 ws->secstart = ws->notestart + ws->notesize; 1180 ws->secoff = ws->secstart; 1181 1182 /* Fill in the PT_NOTE segment header in the last slot */ 1183 note = &ws->psections[ws->npsections - 1]; 1184 note->p_type = PT_NOTE; 1185 note->p_offset = ws->notestart; 1186 note->p_vaddr = 0; 1187 note->p_paddr = 0; 1188 note->p_filesz = ws->notesize; 1189 note->p_memsz = 0; 1190 note->p_flags = PF_R; 1191 note->p_align = ELFROUNDSIZE; 1192 1193 return (0); 1194 } 1195 1196 int 1197 coredump_walk_elf(vaddr_t start, vaddr_t realend, vaddr_t end, vm_prot_t prot, 1198 int nsegment, void *cookie) 1199 { 1200 struct writesegs_state *ws = cookie; 1201 Elf_Phdr phdr; 1202 vsize_t size, realsize; 1203 1204 size = end - start; 1205 realsize = realend - start; 1206 1207 phdr.p_type = PT_LOAD; 1208 phdr.p_offset = ws->secoff; 1209 phdr.p_vaddr = start; 1210 phdr.p_paddr = 0; 1211 phdr.p_filesz = realsize; 1212 phdr.p_memsz = size; 1213 phdr.p_flags = 0; 1214 if (prot & PROT_READ) 1215 phdr.p_flags |= PF_R; 1216 if (prot & PROT_WRITE) 1217 phdr.p_flags |= PF_W; 1218 if (prot & PROT_EXEC) 1219 phdr.p_flags |= PF_X; 1220 phdr.p_align = PAGE_SIZE; 1221 1222 ws->secoff += phdr.p_filesz; 1223 ws->psections[nsegment] = phdr; 1224 1225 return (0); 1226 } 1227 1228 int 1229 coredump_notes_elf(struct proc *p, void *iocookie, size_t *sizep) 1230 { 1231 struct ps_strings pss; 1232 struct iovec iov; 1233 struct uio uio; 1234 struct elfcore_procinfo cpi; 1235 Elf_Note nhdr; 1236 struct process *pr = p->p_p; 1237 struct proc *q; 1238 size_t size, notesize; 1239 int error; 1240 1241 size = 0; 1242 1243 /* First, write an elfcore_procinfo. */ 1244 notesize = sizeof(nhdr) + elfround(sizeof("OpenBSD")) + 1245 elfround(sizeof(cpi)); 1246 if (iocookie) { 1247 memset(&cpi, 0, sizeof(cpi)); 1248 1249 cpi.cpi_version = ELFCORE_PROCINFO_VERSION; 1250 cpi.cpi_cpisize = sizeof(cpi); 1251 cpi.cpi_signo = p->p_sisig; 1252 cpi.cpi_sigcode = p->p_sicode; 1253 1254 cpi.cpi_sigpend = p->p_siglist | pr->ps_siglist; 1255 cpi.cpi_sigmask = p->p_sigmask; 1256 cpi.cpi_sigignore = pr->ps_sigacts->ps_sigignore; 1257 cpi.cpi_sigcatch = pr->ps_sigacts->ps_sigcatch; 1258 1259 cpi.cpi_pid = pr->ps_pid; 1260 cpi.cpi_ppid = pr->ps_pptr->ps_pid; 1261 cpi.cpi_pgrp = pr->ps_pgid; 1262 if (pr->ps_session->s_leader) 1263 cpi.cpi_sid = pr->ps_session->s_leader->ps_pid; 1264 else 1265 cpi.cpi_sid = 0; 1266 1267 cpi.cpi_ruid = p->p_ucred->cr_ruid; 1268 cpi.cpi_euid = p->p_ucred->cr_uid; 1269 cpi.cpi_svuid = p->p_ucred->cr_svuid; 1270 1271 cpi.cpi_rgid = p->p_ucred->cr_rgid; 1272 cpi.cpi_egid = p->p_ucred->cr_gid; 1273 cpi.cpi_svgid = p->p_ucred->cr_svgid; 1274 1275 (void)strlcpy(cpi.cpi_name, pr->ps_comm, sizeof(cpi.cpi_name)); 1276 1277 nhdr.namesz = sizeof("OpenBSD"); 1278 nhdr.descsz = sizeof(cpi); 1279 nhdr.type = NT_OPENBSD_PROCINFO; 1280 1281 error = coredump_writenote_elf(p, iocookie, &nhdr, 1282 "OpenBSD", &cpi); 1283 if (error) 1284 return (error); 1285 } 1286 size += notesize; 1287 1288 /* Second, write an NT_OPENBSD_AUXV note. */ 1289 notesize = sizeof(nhdr) + elfround(sizeof("OpenBSD")) + 1290 elfround(pr->ps_emul->e_arglen * sizeof(char *)); 1291 if (iocookie) { 1292 iov.iov_base = &pss; 1293 iov.iov_len = sizeof(pss); 1294 uio.uio_iov = &iov; 1295 uio.uio_iovcnt = 1; 1296 uio.uio_offset = (off_t)pr->ps_strings; 1297 uio.uio_resid = sizeof(pss); 1298 uio.uio_segflg = UIO_SYSSPACE; 1299 uio.uio_rw = UIO_READ; 1300 uio.uio_procp = NULL; 1301 1302 error = uvm_io(&p->p_vmspace->vm_map, &uio, 0); 1303 if (error) 1304 return (error); 1305 1306 if (pss.ps_envstr == NULL) 1307 return (EIO); 1308 1309 nhdr.namesz = sizeof("OpenBSD"); 1310 nhdr.descsz = pr->ps_emul->e_arglen * sizeof(char *); 1311 nhdr.type = NT_OPENBSD_AUXV; 1312 1313 error = coredump_write(iocookie, UIO_SYSSPACE, 1314 &nhdr, sizeof(nhdr)); 1315 if (error) 1316 return (error); 1317 1318 error = coredump_write(iocookie, UIO_SYSSPACE, 1319 "OpenBSD", elfround(nhdr.namesz)); 1320 if (error) 1321 return (error); 1322 1323 error = coredump_write(iocookie, UIO_USERSPACE, 1324 pss.ps_envstr + pss.ps_nenvstr + 1, nhdr.descsz); 1325 if (error) 1326 return (error); 1327 } 1328 size += notesize; 1329 1330 #ifdef PT_WCOOKIE 1331 notesize = sizeof(nhdr) + elfround(sizeof("OpenBSD")) + 1332 elfround(sizeof(register_t)); 1333 if (iocookie) { 1334 register_t wcookie; 1335 1336 nhdr.namesz = sizeof("OpenBSD"); 1337 nhdr.descsz = sizeof(register_t); 1338 nhdr.type = NT_OPENBSD_WCOOKIE; 1339 1340 wcookie = process_get_wcookie(p); 1341 error = coredump_writenote_elf(p, iocookie, &nhdr, 1342 "OpenBSD", &wcookie); 1343 if (error) 1344 return (error); 1345 } 1346 size += notesize; 1347 #endif 1348 1349 /* 1350 * Now write the register info for the thread that caused the 1351 * coredump. 1352 */ 1353 error = coredump_note_elf(p, iocookie, ¬esize); 1354 if (error) 1355 return (error); 1356 size += notesize; 1357 1358 /* 1359 * Now, for each thread, write the register info and any other 1360 * per-thread notes. Since we're dumping core, all the other 1361 * threads in the process have been stopped and the list can't 1362 * change. 1363 */ 1364 SMR_TAILQ_FOREACH_LOCKED(q, &pr->ps_threads, p_thr_link) { 1365 if (q == p) /* we've taken care of this thread */ 1366 continue; 1367 error = coredump_note_elf(q, iocookie, ¬esize); 1368 if (error) 1369 return (error); 1370 size += notesize; 1371 } 1372 1373 *sizep = size; 1374 return (0); 1375 } 1376 1377 int 1378 coredump_note_elf(struct proc *p, void *iocookie, size_t *sizep) 1379 { 1380 Elf_Note nhdr; 1381 int size, notesize, error; 1382 int namesize; 1383 char name[64+ELFROUNDSIZE]; 1384 struct reg intreg; 1385 #ifdef PT_GETFPREGS 1386 struct fpreg freg; 1387 #endif 1388 1389 size = 0; 1390 1391 snprintf(name, sizeof(name)-ELFROUNDSIZE, "%s@%d", 1392 "OpenBSD", p->p_tid + THREAD_PID_OFFSET); 1393 namesize = strlen(name) + 1; 1394 memset(name + namesize, 0, elfround(namesize) - namesize); 1395 1396 notesize = sizeof(nhdr) + elfround(namesize) + elfround(sizeof(intreg)); 1397 if (iocookie) { 1398 error = process_read_regs(p, &intreg); 1399 if (error) 1400 return (error); 1401 1402 nhdr.namesz = namesize; 1403 nhdr.descsz = sizeof(intreg); 1404 nhdr.type = NT_OPENBSD_REGS; 1405 1406 error = coredump_writenote_elf(p, iocookie, &nhdr, 1407 name, &intreg); 1408 if (error) 1409 return (error); 1410 1411 } 1412 size += notesize; 1413 1414 #ifdef PT_GETFPREGS 1415 notesize = sizeof(nhdr) + elfround(namesize) + elfround(sizeof(freg)); 1416 if (iocookie) { 1417 error = process_read_fpregs(p, &freg); 1418 if (error) 1419 return (error); 1420 1421 nhdr.namesz = namesize; 1422 nhdr.descsz = sizeof(freg); 1423 nhdr.type = NT_OPENBSD_FPREGS; 1424 1425 error = coredump_writenote_elf(p, iocookie, &nhdr, name, &freg); 1426 if (error) 1427 return (error); 1428 } 1429 size += notesize; 1430 #endif 1431 1432 *sizep = size; 1433 /* XXX Add hook for machdep per-LWP notes. */ 1434 return (0); 1435 } 1436 1437 int 1438 coredump_writenote_elf(struct proc *p, void *cookie, Elf_Note *nhdr, 1439 const char *name, void *data) 1440 { 1441 int error; 1442 1443 error = coredump_write(cookie, UIO_SYSSPACE, nhdr, sizeof(*nhdr)); 1444 if (error) 1445 return error; 1446 1447 error = coredump_write(cookie, UIO_SYSSPACE, name, 1448 elfround(nhdr->namesz)); 1449 if (error) 1450 return error; 1451 1452 return coredump_write(cookie, UIO_SYSSPACE, data, nhdr->descsz); 1453 } 1454 #endif /* !SMALL_KERNEL */ 1455