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