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