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