1 /* $OpenBSD: exec_elf.c,v 1.49 2003/11/03 19:58:22 tedu 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 #include <sys/param.h> 35 #include <sys/systm.h> 36 #include <sys/kernel.h> 37 #include <sys/proc.h> 38 #include <sys/malloc.h> 39 #include <sys/mount.h> 40 #include <sys/namei.h> 41 #include <sys/vnode.h> 42 #include <sys/exec.h> 43 #include <sys/exec_elf.h> 44 #include <sys/exec_olf.h> 45 #include <sys/file.h> 46 #include <sys/syscall.h> 47 #include <sys/signalvar.h> 48 #include <sys/stat.h> 49 50 #include <sys/mman.h> 51 #include <uvm/uvm_extern.h> 52 53 #include <machine/cpu.h> 54 #include <machine/reg.h> 55 #include <machine/exec.h> 56 57 #ifdef COMPAT_LINUX 58 #include <compat/linux/linux_exec.h> 59 #endif 60 61 #ifdef COMPAT_SVR4 62 #include <compat/svr4/svr4_exec.h> 63 #endif 64 65 #ifdef COMPAT_FREEBSD 66 #include <compat/freebsd/freebsd_exec.h> 67 #endif 68 69 #ifdef COMPAT_NETBSD 70 #include <compat/netbsd/netbsd_exec.h> 71 #endif 72 73 struct ELFNAME(probe_entry) { 74 int (*func)(struct proc *, struct exec_package *, char *, 75 u_long *, u_int8_t *); 76 int os_mask; 77 } ELFNAME(probes)[] = { 78 /* XXX - bogus, shouldn't be size independent.. */ 79 #ifdef COMPAT_FREEBSD 80 { freebsd_elf_probe, 1 << OOS_FREEBSD }, 81 #endif 82 #ifdef COMPAT_SVR4 83 { svr4_elf_probe, 84 1 << OOS_SVR4 | 1 << OOS_ESIX | 1 << OOS_SOLARIS | 1 << OOS_SCO | 85 1 << OOS_DELL | 1 << OOS_NCR }, 86 #endif 87 #ifdef COMPAT_LINUX 88 { linux_elf_probe, 1 << OOS_LINUX }, 89 #endif 90 #ifdef COMPAT_NETBSD 91 { netbsd_elf64_probe, 1 << OOS_NETBSD }, 92 #endif 93 { 0, 1 << OOS_OPENBSD } 94 }; 95 96 int ELFNAME(load_file)(struct proc *, char *, struct exec_package *, 97 struct elf_args *, Elf_Addr *); 98 int ELFNAME(check_header)(Elf_Ehdr *, int); 99 int ELFNAME(olf_check_header)(Elf_Ehdr *, int, u_int8_t *); 100 int ELFNAME(read_from)(struct proc *, struct vnode *, u_long, caddr_t, int); 101 void ELFNAME(load_psection)(struct exec_vmcmd_set *, struct vnode *, 102 Elf_Phdr *, Elf_Addr *, Elf_Addr *, int *, int); 103 104 extern char sigcode[], esigcode[]; 105 #ifdef SYSCALL_DEBUG 106 extern char *syscallnames[]; 107 #endif 108 109 /* round up and down to page boundaries. */ 110 #define ELF_ROUND(a, b) (((a) + (b) - 1) & ~((b) - 1)) 111 #define ELF_TRUNC(a, b) ((a) & ~((b) - 1)) 112 113 /* 114 * We limit the number of program headers to 32, this should 115 * be a reasonable limit for ELF, the most we have seen so far is 12 116 */ 117 #define ELF_MAX_VALID_PHDR 32 118 119 /* 120 * This is the basic elf emul. elf_probe_funcs may change to other emuls. 121 */ 122 struct emul ELFNAMEEND(emul) = { 123 "native", 124 NULL, 125 sendsig, 126 SYS_syscall, 127 SYS_MAXSYSCALL, 128 sysent, 129 #ifdef SYSCALL_DEBUG 130 syscallnames, 131 #else 132 NULL, 133 #endif 134 sizeof (AuxInfo) * ELF_AUX_ENTRIES, 135 ELFNAME(copyargs), 136 setregs, 137 ELFNAME2(exec,fixup), 138 sigcode, 139 esigcode, 140 EMUL_ENABLED | EMUL_NATIVE, 141 }; 142 143 /* 144 * Copy arguments onto the stack in the normal way, but add some 145 * space for extra information in case of dynamic binding. 146 */ 147 void * 148 ELFNAME(copyargs)(struct exec_package *pack, struct ps_strings *arginfo, 149 void *stack, void *argp) 150 { 151 stack = copyargs(pack, arginfo, stack, argp); 152 if (!stack) 153 return (NULL); 154 155 /* 156 * Push space for extra arguments on the stack needed by 157 * dynamically linked binaries. 158 */ 159 if (pack->ep_interp != NULL) { 160 pack->ep_emul_argp = stack; 161 stack += ELF_AUX_ENTRIES * sizeof (AuxInfo); 162 } 163 return (stack); 164 } 165 166 /* 167 * Check header for validity; return 0 for ok, ENOEXEC if error 168 */ 169 int 170 ELFNAME(check_header)(Elf_Ehdr *ehdr, int type) 171 { 172 /* 173 * We need to check magic, class size, endianess, and version before 174 * we look at the rest of the Elf_Ehdr structure. These few elements 175 * are represented in a machine independant fashion. 176 */ 177 if (!IS_ELF(*ehdr) || 178 ehdr->e_ident[EI_CLASS] != ELF_TARG_CLASS || 179 ehdr->e_ident[EI_DATA] != ELF_TARG_DATA || 180 ehdr->e_ident[EI_VERSION] != ELF_TARG_VER) 181 return (ENOEXEC); 182 183 /* Now check the machine dependant header */ 184 if (ehdr->e_machine != ELF_TARG_MACH || 185 ehdr->e_version != ELF_TARG_VER) 186 return (ENOEXEC); 187 188 /* Check the type */ 189 if (ehdr->e_type != type) 190 return (ENOEXEC); 191 192 /* Don't allow an insane amount of sections. */ 193 if (ehdr->e_phnum > ELF_MAX_VALID_PHDR) 194 return (ENOEXEC); 195 196 return (0); 197 } 198 199 /* 200 * Check header for validity; return 0 for ok, ENOEXEC if error. 201 * Remember OS tag for callers sake. 202 */ 203 int 204 ELFNAME(olf_check_header)(Elf_Ehdr *ehdr, int type, u_int8_t *os) 205 { 206 int i; 207 208 /* 209 * We need to check magic, class size, endianess, version, and OS 210 * before we look at the rest of the Elf_Ehdr structure. These few 211 * elements are represented in a machine independant fashion. 212 */ 213 if (!IS_OLF(*ehdr) || 214 ehdr->e_ident[OI_CLASS] != ELF_TARG_CLASS || 215 ehdr->e_ident[OI_DATA] != ELF_TARG_DATA || 216 ehdr->e_ident[OI_VERSION] != ELF_TARG_VER) 217 return (ENOEXEC); 218 219 for (i = 0; 220 i < sizeof(ELFNAME(probes)) / sizeof(ELFNAME(probes)[0]); 221 i++) { 222 if ((1 << ehdr->e_ident[OI_OS]) & ELFNAME(probes)[i].os_mask) 223 goto os_ok; 224 } 225 return (ENOEXEC); 226 227 os_ok: 228 /* Now check the machine dependant header */ 229 if (ehdr->e_machine != ELF_TARG_MACH || 230 ehdr->e_version != ELF_TARG_VER) 231 return (ENOEXEC); 232 233 /* Check the type */ 234 if (ehdr->e_type != type) 235 return (ENOEXEC); 236 237 /* Don't allow an insane amount of sections. */ 238 if (ehdr->e_phnum > ELF_MAX_VALID_PHDR) 239 return (ENOEXEC); 240 241 *os = ehdr->e_ident[OI_OS]; 242 return (0); 243 } 244 245 /* 246 * Load a psection at the appropriate address 247 */ 248 void 249 ELFNAME(load_psection)(struct exec_vmcmd_set *vcset, struct vnode *vp, 250 Elf_Phdr *ph, Elf_Addr *addr, Elf_Addr *size, int *prot, int flags) 251 { 252 u_long uaddr, msize, lsize, psize, rm, rf; 253 long diff, offset, bdiff; 254 Elf_Addr base; 255 256 /* 257 * If the user specified an address, then we load there. 258 */ 259 if (*addr != ELFDEFNNAME(NO_ADDR)) { 260 if (ph->p_align > 1) { 261 *addr = ELF_TRUNC(*addr, ph->p_align); 262 diff = ph->p_vaddr - ELF_TRUNC(ph->p_vaddr, ph->p_align); 263 /* page align vaddr */ 264 base = *addr + trunc_page(ph->p_vaddr) 265 - ELF_TRUNC(ph->p_vaddr, ph->p_align); 266 267 bdiff = ph->p_vaddr - trunc_page(ph->p_vaddr); 268 269 } else 270 diff = 0; 271 } else { 272 *addr = uaddr = ph->p_vaddr; 273 if (ph->p_align > 1) 274 *addr = ELF_TRUNC(uaddr, ph->p_align); 275 base = trunc_page(uaddr); 276 bdiff = uaddr - base; 277 diff = uaddr - *addr; 278 } 279 280 *prot |= (ph->p_flags & PF_R) ? VM_PROT_READ : 0; 281 *prot |= (ph->p_flags & PF_W) ? VM_PROT_WRITE : 0; 282 *prot |= (ph->p_flags & PF_X) ? VM_PROT_EXECUTE : 0; 283 284 msize = ph->p_memsz + diff; 285 offset = ph->p_offset - bdiff; 286 lsize = ph->p_filesz + bdiff; 287 psize = round_page(lsize); 288 289 /* 290 * Because the pagedvn pager can't handle zero fill of the last 291 * data page if it's not page aligned we map the last page readvn. 292 */ 293 if (ph->p_flags & PF_W) { 294 psize = trunc_page(lsize); 295 if (psize > 0) 296 NEW_VMCMD2(vcset, vmcmd_map_pagedvn, psize, base, vp, 297 offset, *prot, flags); 298 if (psize != lsize) { 299 NEW_VMCMD2(vcset, vmcmd_map_readvn, lsize - psize, 300 base + psize, vp, offset + psize, *prot, flags); 301 } 302 } else { 303 NEW_VMCMD2(vcset, vmcmd_map_pagedvn, psize, base, vp, offset, 304 *prot, flags); 305 } 306 307 /* 308 * Check if we need to extend the size of the segment 309 */ 310 rm = round_page(*addr + ph->p_memsz + diff); 311 rf = round_page(*addr + ph->p_filesz + diff); 312 313 if (rm != rf) { 314 NEW_VMCMD2(vcset, vmcmd_map_zero, rm - rf, rf, NULLVP, 0, 315 *prot, flags); 316 } 317 *size = msize; 318 } 319 320 /* 321 * Read from vnode into buffer at offset. 322 */ 323 int 324 ELFNAME(read_from)(struct proc *p, struct vnode *vp, u_long off, caddr_t buf, 325 int size) 326 { 327 int error; 328 size_t resid; 329 330 if ((error = vn_rdwr(UIO_READ, vp, buf, size, off, UIO_SYSSPACE, 331 0, p->p_ucred, &resid, p)) != 0) 332 return error; 333 /* 334 * See if we got all of it 335 */ 336 if (resid != 0) 337 return (ENOEXEC); 338 return (0); 339 } 340 341 /* 342 * Load a file (interpreter/library) pointed to by path [stolen from 343 * coff_load_shlib()]. Made slightly generic so it might be used externally. 344 */ 345 int 346 ELFNAME(load_file)(struct proc *p, char *path, struct exec_package *epp, 347 struct elf_args *ap, Elf_Addr *last) 348 { 349 int error, i; 350 struct nameidata nd; 351 Elf_Ehdr eh; 352 Elf_Phdr *ph = NULL; 353 u_long phsize; 354 char *bp = NULL; 355 Elf_Addr addr; 356 struct vnode *vp; 357 u_int8_t os; /* Just a dummy in this routine */ 358 Elf_Phdr *base_ph = NULL; 359 struct interp_ld_sec { 360 Elf_Addr vaddr; 361 u_long memsz; 362 } loadmap[ELF_MAX_VALID_PHDR]; 363 int nload, idx = 0; 364 Elf_Addr pos = *last; 365 int file_align; 366 367 bp = path; 368 NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_SYSSPACE, path, p); 369 if ((error = namei(&nd)) != 0) { 370 return (error); 371 } 372 vp = nd.ni_vp; 373 if (vp->v_type != VREG) { 374 error = EACCES; 375 goto bad; 376 } 377 if ((error = VOP_GETATTR(vp, epp->ep_vap, p->p_ucred, p)) != 0) 378 goto bad; 379 if (vp->v_mount->mnt_flag & MNT_NOEXEC) { 380 error = EACCES; 381 goto bad; 382 } 383 if ((error = VOP_ACCESS(vp, VREAD, p->p_ucred, p)) != 0) 384 goto bad1; 385 if ((error = ELFNAME(read_from)(p, nd.ni_vp, 0, 386 (caddr_t)&eh, sizeof(eh))) != 0) 387 goto bad1; 388 389 if (ELFNAME(check_header)(&eh, ET_DYN) && 390 ELFNAME(olf_check_header)(&eh, ET_DYN, &os)) { 391 error = ENOEXEC; 392 goto bad1; 393 } 394 395 phsize = eh.e_phnum * sizeof(Elf_Phdr); 396 ph = (Elf_Phdr *)malloc(phsize, M_TEMP, M_WAITOK); 397 398 if ((error = ELFNAME(read_from)(p, nd.ni_vp, eh.e_phoff, (caddr_t)ph, 399 phsize)) != 0) 400 goto bad1; 401 402 for (i = 0; i < eh.e_phnum; i++) { 403 if (ph[i].p_type == PT_LOAD) { 404 loadmap[idx].vaddr = trunc_page(ph[i].p_vaddr); 405 loadmap[idx].memsz = round_page (ph[i].p_vaddr + 406 ph[i].p_memsz - loadmap[idx].vaddr); 407 file_align = ph[i].p_align; 408 idx++; 409 } 410 } 411 nload = idx; 412 413 /* 414 * If no position to load the interpreter was set by a probe 415 * function, pick the same address that a non-fixed mmap(0, ..) 416 * would (i.e. something safely out of the way). 417 */ 418 if (pos == ELFDEFNNAME(NO_ADDR)) { 419 pos = uvm_map_hint(p, VM_PROT_EXECUTE); 420 } 421 422 pos = ELF_ROUND(pos, file_align); 423 *last = epp->ep_interp_pos = pos; 424 for (i = 0; i < nload;/**/) { 425 vaddr_t addr; 426 struct uvm_object *uobj; 427 off_t uoff; 428 size_t size; 429 430 #ifdef this_needs_fixing 431 if (i == 0) { 432 uobj = &vp->v_uvm.u_obj; 433 /* need to fix uoff */ 434 } else { 435 #endif 436 uobj = NULL; 437 uoff = 0; 438 #ifdef this_needs_fixing 439 } 440 #endif 441 442 addr = trunc_page(pos + loadmap[i].vaddr); 443 size = round_page(addr + loadmap[i].memsz) - addr; 444 445 /* CRAP - map_findspace does not avoid daddr+MAXDSIZ */ 446 if ((addr + size > (vaddr_t)p->p_vmspace->vm_daddr) && 447 (addr < (vaddr_t)p->p_vmspace->vm_daddr + MAXDSIZ)) 448 addr = round_page((vaddr_t)p->p_vmspace->vm_daddr + 449 MAXDSIZ); 450 451 if (uvm_map_findspace(&p->p_vmspace->vm_map, addr, size, 452 &addr, uobj, uoff, 0, UVM_FLAG_FIXED) == NULL) { 453 if (uvm_map_findspace(&p->p_vmspace->vm_map, addr, size, 454 &addr, uobj, uoff, 0, 0) == NULL) { 455 error = ENOMEM; /* XXX */ 456 goto bad1; 457 } 458 } 459 if (addr != pos + loadmap[i].vaddr) { 460 /* base changed. */ 461 pos = addr - trunc_page(loadmap[i].vaddr); 462 pos = ELF_ROUND(pos,file_align); 463 epp->ep_interp_pos = *last = pos; 464 i = 0; 465 continue; 466 } 467 468 i++; 469 } 470 471 /* 472 * Load all the necessary sections 473 */ 474 for (i = 0; i < eh.e_phnum; i++) { 475 Elf_Addr size = 0; 476 int prot = 0; 477 int flags; 478 479 switch (ph[i].p_type) { 480 case PT_LOAD: 481 if (base_ph == NULL) { 482 flags = VMCMD_BASE; 483 addr = *last; 484 base_ph = &ph[i]; 485 } else { 486 flags = VMCMD_RELATIVE; 487 addr = ph[i].p_vaddr - base_ph->p_vaddr; 488 } 489 ELFNAME(load_psection)(&epp->ep_vmcmds, nd.ni_vp, 490 &ph[i], &addr, &size, &prot, flags); 491 /* If entry is within this section it must be text */ 492 if (eh.e_entry >= ph[i].p_vaddr && 493 eh.e_entry < (ph[i].p_vaddr + size)) { 494 epp->ep_entry = addr + eh.e_entry - 495 ELF_TRUNC(ph[i].p_vaddr,ph[i].p_align); 496 ap->arg_interp = addr; 497 } 498 addr += size; 499 break; 500 501 case PT_DYNAMIC: 502 case PT_PHDR: 503 case PT_NOTE: 504 break; 505 506 default: 507 break; 508 } 509 } 510 511 vn_marktext(nd.ni_vp); 512 513 bad1: 514 VOP_CLOSE(nd.ni_vp, FREAD, p->p_ucred, p); 515 bad: 516 if (ph != NULL) 517 free((char *)ph, M_TEMP); 518 519 *last = addr; 520 vput(nd.ni_vp); 521 return (error); 522 } 523 524 /* 525 * Prepare an Elf binary's exec package 526 * 527 * First, set of the various offsets/lengths in the exec package. 528 * 529 * Then, mark the text image busy (so it can be demand paged) or error out if 530 * this is not possible. Finally, set up vmcmds for the text, data, bss, and 531 * stack segments. 532 */ 533 int 534 ELFNAME2(exec,makecmds)(struct proc *p, struct exec_package *epp) 535 { 536 Elf_Ehdr *eh = epp->ep_hdr; 537 Elf_Phdr *ph, *pp; 538 Elf_Addr phdr = 0; 539 int error, i; 540 char interp[MAXPATHLEN]; 541 u_long pos = 0, phsize; 542 u_int8_t os = OOS_NULL; 543 544 if (epp->ep_hdrvalid < sizeof(Elf_Ehdr)) 545 return (ENOEXEC); 546 547 if (ELFNAME(check_header)(eh, ET_EXEC) && 548 ELFNAME(olf_check_header)(eh, ET_EXEC, &os)) 549 return (ENOEXEC); 550 551 /* 552 * check if vnode is in open for writing, because we want to demand- 553 * page out of it. if it is, don't do it, for various reasons. 554 */ 555 if (epp->ep_vp->v_writecount != 0) { 556 #ifdef DIAGNOSTIC 557 if (epp->ep_vp->v_flag & VTEXT) 558 panic("exec: a VTEXT vnode has writecount != 0"); 559 #endif 560 return (ETXTBSY); 561 } 562 /* 563 * Allocate space to hold all the program headers, and read them 564 * from the file 565 */ 566 phsize = eh->e_phnum * sizeof(Elf_Phdr); 567 ph = (Elf_Phdr *)malloc(phsize, M_TEMP, M_WAITOK); 568 569 if ((error = ELFNAME(read_from)(p, epp->ep_vp, eh->e_phoff, (caddr_t)ph, 570 phsize)) != 0) 571 goto bad; 572 573 epp->ep_tsize = ELFDEFNNAME(NO_ADDR); 574 epp->ep_dsize = ELFDEFNNAME(NO_ADDR); 575 576 interp[0] = '\0'; 577 578 for (i = 0; i < eh->e_phnum; i++) { 579 pp = &ph[i]; 580 if (pp->p_type == PT_INTERP) { 581 if (pp->p_filesz >= sizeof(interp)) 582 goto bad; 583 if ((error = ELFNAME(read_from)(p, epp->ep_vp, 584 pp->p_offset, (caddr_t)interp, pp->p_filesz)) != 0) 585 goto bad; 586 break; 587 } 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 p->p_os = OOS_OPENBSD; 608 #ifdef NATIVE_EXEC_ELF 609 if (ELFNAME(os_pt_note)(p, epp, epp->ep_hdr, "OpenBSD", 8, 4) == 0) { 610 goto native; 611 } 612 #endif 613 for (i = 0; 614 i < sizeof(ELFNAME(probes)) / sizeof(ELFNAME(probes)[0]) && error; 615 i++) { 616 if (os == OOS_NULL || ((1 << os) & ELFNAME(probes)[i].os_mask)) 617 error = ELFNAME(probes)[i].func ? 618 (*ELFNAME(probes)[i].func)(p, epp, interp, &pos, &os) : 619 0; 620 } 621 if (!error) 622 p->p_os = os; 623 #ifndef NATIVE_EXEC_ELF 624 else 625 goto bad; 626 #else 627 native: 628 #endif /* NATIVE_EXEC_ELF */ 629 /* 630 * Load all the necessary sections 631 */ 632 for (i = 0; i < eh->e_phnum; i++) { 633 Elf_Addr addr = ELFDEFNNAME(NO_ADDR), size = 0; 634 int prot = 0; 635 636 pp = &ph[i]; 637 638 switch (ph[i].p_type) { 639 case PT_LOAD: 640 /* 641 * Calcuates size of text and data segments 642 * by starting at first and going to end of last. 643 * 'rwx' sections are treated as data. 644 * this is correct for BSS_PLT, but may not be 645 * for DATA_PLT, is fine for TEXT_PLT. 646 */ 647 ELFNAME(load_psection)(&epp->ep_vmcmds, epp->ep_vp, 648 &ph[i], &addr, &size, &prot, 0); 649 /* 650 * Decide whether it's text or data by looking 651 * at the protection of the section 652 */ 653 if (prot & VM_PROT_WRITE) { 654 /* data section */ 655 if (epp->ep_dsize == ELFDEFNNAME(NO_ADDR)) { 656 epp->ep_daddr = addr; 657 epp->ep_dsize = size; 658 } else { 659 if (addr < epp->ep_daddr) { 660 epp->ep_dsize = 661 epp->ep_dsize + 662 epp->ep_daddr - 663 addr; 664 epp->ep_daddr = addr; 665 } else 666 epp->ep_dsize = addr+size - 667 epp->ep_daddr; 668 } 669 } else if (prot & VM_PROT_EXECUTE) { 670 /* text section */ 671 if (epp->ep_tsize == ELFDEFNNAME(NO_ADDR)) { 672 epp->ep_taddr = addr; 673 epp->ep_tsize = size; 674 } else { 675 if (addr < epp->ep_taddr) { 676 epp->ep_tsize = 677 epp->ep_tsize + 678 epp->ep_taddr - 679 addr; 680 epp->ep_taddr = addr; 681 } else 682 epp->ep_tsize = addr+size - 683 epp->ep_taddr; 684 } 685 } 686 break; 687 688 case PT_SHLIB: 689 error = ENOEXEC; 690 goto bad; 691 692 case PT_INTERP: 693 /* Already did this one */ 694 case PT_DYNAMIC: 695 case PT_NOTE: 696 break; 697 698 case PT_PHDR: 699 /* Note address of program headers (in text segment) */ 700 phdr = pp->p_vaddr; 701 break; 702 703 default: 704 /* 705 * Not fatal, we don't need to understand everything 706 * :-) 707 */ 708 break; 709 } 710 } 711 712 /* 713 * Check if we found a dynamically linked binary and arrange to load 714 * it's interpreter when the exec file is released. 715 */ 716 if (interp[0]) { 717 char *ip; 718 struct elf_args *ap; 719 720 ip = (char *)malloc(MAXPATHLEN, M_TEMP, M_WAITOK); 721 ap = (struct elf_args *) 722 malloc(sizeof(struct elf_args), M_TEMP, M_WAITOK); 723 724 bcopy(interp, ip, MAXPATHLEN); 725 epp->ep_interp = ip; 726 epp->ep_interp_pos = pos; 727 728 ap->arg_phaddr = phdr; 729 ap->arg_phentsize = eh->e_phentsize; 730 ap->arg_phnum = eh->e_phnum; 731 ap->arg_entry = eh->e_entry; 732 ap->arg_os = os; 733 734 epp->ep_emul_arg = ap; 735 epp->ep_entry = eh->e_entry; /* keep check_exec() happy */ 736 } else { 737 epp->ep_interp = NULL; 738 epp->ep_entry = eh->e_entry; 739 } 740 741 #if defined(COMPAT_SVR4) && defined(i386) 742 #ifndef ELF_MAP_PAGE_ZERO 743 /* Dell SVR4 maps page zero, yeuch! */ 744 if (p->p_os == OOS_DELL) 745 #endif 746 NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_readvn, PAGE_SIZE, 0, 747 epp->ep_vp, 0, VM_PROT_READ); 748 #endif 749 750 free((char *)ph, M_TEMP); 751 vn_marktext(epp->ep_vp); 752 return (exec_setup_stack(p, epp)); 753 754 bad: 755 free((char *)ph, M_TEMP); 756 kill_vmcmds(&epp->ep_vmcmds); 757 return (ENOEXEC); 758 } 759 760 /* 761 * Phase II of load. It is now safe to load the interpreter. Info collected 762 * when loading the program is available for setup of the interpreter. 763 */ 764 int 765 ELFNAME2(exec,fixup)(struct proc *p, struct exec_package *epp) 766 { 767 char *interp; 768 int error; 769 struct elf_args *ap; 770 AuxInfo ai[ELF_AUX_ENTRIES], *a; 771 Elf_Addr pos = epp->ep_interp_pos; 772 773 if (epp->ep_interp == NULL) { 774 return (0); 775 } 776 777 interp = (char *)epp->ep_interp; 778 ap = (struct elf_args *)epp->ep_emul_arg; 779 780 if ((error = ELFNAME(load_file)(p, interp, epp, ap, &pos)) != 0) { 781 free((char *)ap, M_TEMP); 782 free((char *)interp, M_TEMP); 783 kill_vmcmds(&epp->ep_vmcmds); 784 return (error); 785 } 786 /* 787 * We have to do this ourselves... 788 */ 789 error = exec_process_vmcmds(p, epp); 790 791 /* 792 * Push extra arguments on the stack needed by dynamically 793 * linked binaries 794 */ 795 if (error == 0) { 796 a = ai; 797 798 a->au_id = AUX_phdr; 799 a->au_v = ap->arg_phaddr; 800 a++; 801 802 a->au_id = AUX_phent; 803 a->au_v = ap->arg_phentsize; 804 a++; 805 806 a->au_id = AUX_phnum; 807 a->au_v = ap->arg_phnum; 808 a++; 809 810 a->au_id = AUX_pagesz; 811 a->au_v = PAGE_SIZE; 812 a++; 813 814 a->au_id = AUX_base; 815 a->au_v = ap->arg_interp; 816 a++; 817 818 a->au_id = AUX_flags; 819 a->au_v = 0; 820 a++; 821 822 a->au_id = AUX_entry; 823 a->au_v = ap->arg_entry; 824 a++; 825 826 a->au_id = AUX_null; 827 a->au_v = 0; 828 a++; 829 830 error = copyout(ai, epp->ep_emul_argp, sizeof ai); 831 } 832 free((char *)ap, M_TEMP); 833 free((char *)interp, M_TEMP); 834 return (error); 835 } 836 837 /* 838 * Older ELF binaries use EI_ABIVERSION (formerly EI_BRAND) to brand 839 * executables. Newer ELF binaries use EI_OSABI instead. 840 */ 841 char * 842 ELFNAME(check_brand)(Elf_Ehdr *eh) 843 { 844 if (eh->e_ident[EI_ABIVERSION] == '\0') 845 return (NULL); 846 return (&eh->e_ident[EI_ABIVERSION]); 847 } 848 849 int 850 ELFNAME(os_pt_note)(struct proc *p, struct exec_package *epp, Elf_Ehdr *eh, 851 char *os_name, size_t name_size, size_t desc_size) 852 { 853 Elf_Phdr *hph, *ph; 854 Elf_Note *np = NULL; 855 size_t phsize; 856 int error; 857 858 phsize = eh->e_phnum * sizeof(Elf_Phdr); 859 hph = (Elf_Phdr *)malloc(phsize, M_TEMP, M_WAITOK); 860 if ((error = ELFNAME(read_from)(p, epp->ep_vp, eh->e_phoff, 861 (caddr_t)hph, phsize)) != 0) 862 goto out1; 863 864 for (ph = hph; ph < &hph[eh->e_phnum]; ph++) { 865 if (ph->p_type != PT_NOTE || 866 ph->p_filesz > 1024 || 867 ph->p_filesz < sizeof(Elf_Note) + name_size) 868 continue; 869 870 np = (Elf_Note *)malloc(ph->p_filesz, M_TEMP, M_WAITOK); 871 if ((error = ELFNAME(read_from)(p, epp->ep_vp, ph->p_offset, 872 (caddr_t)np, ph->p_filesz)) != 0) 873 goto out2; 874 875 #if 0 876 if (np->type != ELF_NOTE_TYPE_OSVERSION) { 877 free(np, M_TEMP); 878 np = NULL; 879 continue; 880 } 881 #endif 882 883 /* Check the name and description sizes. */ 884 if (np->namesz != name_size || 885 np->descsz != desc_size) 886 goto out3; 887 888 if (bcmp((np + 1), os_name, name_size)) 889 goto out3; 890 891 /* XXX: We could check for the specific emulation here */ 892 /* All checks succeeded. */ 893 error = 0; 894 goto out2; 895 } 896 897 out3: 898 error = ENOEXEC; 899 out2: 900 if (np) 901 free(np, M_TEMP); 902 out1: 903 free(hph, M_TEMP); 904 return error; 905 } 906