1 /* $OpenBSD: exec_elf.c,v 1.43 2002/11/22 22:10:21 drahn 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 * This is the basic elf emul. elf_probe_funcs may change to other emuls. 115 */ 116 struct emul ELFNAMEEND(emul) = { 117 "native", 118 NULL, 119 sendsig, 120 SYS_syscall, 121 SYS_MAXSYSCALL, 122 sysent, 123 #ifdef SYSCALL_DEBUG 124 syscallnames, 125 #else 126 NULL, 127 #endif 128 sizeof (AuxInfo) * ELF_AUX_ENTRIES, 129 ELFNAME(copyargs), 130 setregs, 131 ELFNAME2(exec,fixup), 132 sigcode, 133 esigcode, 134 }; 135 136 /* 137 * Copy arguments onto the stack in the normal way, but add some 138 * space for extra information in case of dynamic binding. 139 */ 140 void * 141 ELFNAME(copyargs)(struct exec_package *pack, struct ps_strings *arginfo, 142 void *stack, void *argp) 143 { 144 stack = copyargs(pack, arginfo, stack, argp); 145 if (!stack) 146 return (NULL); 147 148 /* 149 * Push space for extra arguments on the stack needed by 150 * dynamically linked binaries. 151 */ 152 if (pack->ep_interp != NULL) { 153 pack->ep_emul_argp = stack; 154 stack += ELF_AUX_ENTRIES * sizeof (AuxInfo); 155 } 156 return (stack); 157 } 158 159 /* 160 * Check header for validity; return 0 for ok, ENOEXEC if error 161 */ 162 int 163 ELFNAME(check_header)(Elf_Ehdr *ehdr, int type) 164 { 165 /* 166 * We need to check magic, class size, endianess, and version before 167 * we look at the rest of the Elf_Ehdr structure. These few elements 168 * are represented in a machine independant fashion. 169 */ 170 if (!IS_ELF(*ehdr) || 171 ehdr->e_ident[EI_CLASS] != ELF_TARG_CLASS || 172 ehdr->e_ident[EI_DATA] != ELF_TARG_DATA || 173 ehdr->e_ident[EI_VERSION] != ELF_TARG_VER) 174 return (ENOEXEC); 175 176 /* Now check the machine dependant header */ 177 if (ehdr->e_machine != ELF_TARG_MACH || 178 ehdr->e_version != ELF_TARG_VER) 179 return (ENOEXEC); 180 181 /* Check the type */ 182 if (ehdr->e_type != type) 183 return (ENOEXEC); 184 185 /* Don't allow an insane amount of sections. */ 186 if (ehdr->e_phnum > 128) 187 return (ENOEXEC); 188 189 return (0); 190 } 191 192 /* 193 * Check header for validity; return 0 for ok, ENOEXEC if error. 194 * Remeber OS tag for callers sake. 195 */ 196 int 197 ELFNAME(olf_check_header)(Elf_Ehdr *ehdr, int type, u_int8_t *os) 198 { 199 int i; 200 201 /* 202 * We need to check magic, class size, endianess, version, and OS 203 * before we look at the rest of the Elf_Ehdr structure. These few 204 * elements are represented in a machine independant fashion. 205 */ 206 if (!IS_OLF(*ehdr) || 207 ehdr->e_ident[OI_CLASS] != ELF_TARG_CLASS || 208 ehdr->e_ident[OI_DATA] != ELF_TARG_DATA || 209 ehdr->e_ident[OI_VERSION] != ELF_TARG_VER) 210 return (ENOEXEC); 211 212 for (i = 0; 213 i < sizeof(ELFNAME(probes)) / sizeof(ELFNAME(probes)[0]); 214 i++) { 215 if ((1 << ehdr->e_ident[OI_OS]) & ELFNAME(probes)[i].os_mask) 216 goto os_ok; 217 } 218 return (ENOEXEC); 219 220 os_ok: 221 /* Now check the machine dependant header */ 222 if (ehdr->e_machine != ELF_TARG_MACH || 223 ehdr->e_version != ELF_TARG_VER) 224 return (ENOEXEC); 225 226 /* Check the type */ 227 if (ehdr->e_type != type) 228 return (ENOEXEC); 229 230 /* Don't allow an insane amount of sections. */ 231 if (ehdr->e_phnum > 128) 232 return (ENOEXEC); 233 234 *os = ehdr->e_ident[OI_OS]; 235 return (0); 236 } 237 238 /* 239 * Load a psection at the appropriate address 240 */ 241 void 242 ELFNAME(load_psection)(struct exec_vmcmd_set *vcset, struct vnode *vp, 243 Elf_Phdr *ph, Elf_Addr *addr, Elf_Addr *size, int *prot, int flags) 244 { 245 u_long uaddr, msize, psize, rm, rf; 246 long diff, offset; 247 248 /* 249 * If the user specified an address, then we load there. 250 */ 251 if (*addr != ELFDEFNNAME(NO_ADDR)) { 252 if (ph->p_align > 1) { 253 *addr = ELF_TRUNC(*addr, ph->p_align); 254 diff = ph->p_vaddr - ELF_TRUNC(ph->p_vaddr, ph->p_align); 255 } else 256 diff = 0; 257 } else { 258 *addr = uaddr = ph->p_vaddr; 259 if (ph->p_align > 1) 260 *addr = ELF_TRUNC(uaddr, ph->p_align); 261 diff = uaddr - *addr; 262 } 263 264 *prot |= (ph->p_flags & PF_R) ? VM_PROT_READ : 0; 265 *prot |= (ph->p_flags & PF_W) ? VM_PROT_WRITE : 0; 266 *prot |= (ph->p_flags & PF_X) ? VM_PROT_EXECUTE : 0; 267 268 offset = ph->p_offset - diff; 269 *size = ph->p_filesz + diff; 270 msize = ph->p_memsz + diff; 271 psize = round_page(*size); 272 273 /* 274 * Because the pagedvn pager can't handle zero fill of the last 275 * data page if it's not page aligned we map the last page readvn. 276 */ 277 if (ph->p_flags & PF_W) { 278 psize = trunc_page(*size); 279 if (psize > 0) 280 NEW_VMCMD2(vcset, vmcmd_map_pagedvn, psize, *addr, vp, 281 offset, *prot, flags); 282 if (psize != *size) { 283 NEW_VMCMD2(vcset, vmcmd_map_readvn, *size - psize, 284 *addr + psize, vp, offset + psize, *prot, flags); 285 } 286 } else { 287 NEW_VMCMD2(vcset, vmcmd_map_pagedvn, psize, *addr, vp, offset, 288 *prot, flags); 289 } 290 291 /* 292 * Check if we need to extend the size of the segment 293 */ 294 rm = round_page(*addr + msize); 295 rf = round_page(*addr + *size); 296 297 if (rm != rf) { 298 NEW_VMCMD2(vcset, vmcmd_map_zero, rm - rf, rf, NULLVP, 0, 299 *prot, flags); 300 *size = msize; 301 } 302 } 303 304 /* 305 * Read from vnode into buffer at offset. 306 */ 307 int 308 ELFNAME(read_from)(struct proc *p, struct vnode *vp, u_long off, caddr_t buf, 309 int size) 310 { 311 int error; 312 size_t resid; 313 314 if ((error = vn_rdwr(UIO_READ, vp, buf, size, off, UIO_SYSSPACE, 315 0, p->p_ucred, &resid, p)) != 0) 316 return error; 317 /* 318 * See if we got all of it 319 */ 320 if (resid != 0) 321 return (ENOEXEC); 322 return (0); 323 } 324 325 /* 326 * Load a file (interpreter/library) pointed to by path [stolen from 327 * coff_load_shlib()]. Made slightly generic so it might be used externally. 328 */ 329 int 330 ELFNAME(load_file)(struct proc *p, char *path, struct exec_package *epp, 331 struct elf_args *ap, Elf_Addr *last) 332 { 333 int error, i; 334 struct nameidata nd; 335 Elf_Ehdr eh; 336 Elf_Phdr *ph = NULL; 337 u_long phsize; 338 char *bp = NULL; 339 Elf_Addr addr; 340 struct vnode *vp; 341 u_int8_t os; /* Just a dummy in this routine */ 342 Elf_Phdr *base_ph = NULL; 343 344 bp = path; 345 NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_SYSSPACE, path, p); 346 if ((error = namei(&nd)) != 0) { 347 return (error); 348 } 349 vp = nd.ni_vp; 350 if (vp->v_type != VREG) { 351 error = EACCES; 352 goto bad; 353 } 354 if ((error = VOP_GETATTR(vp, epp->ep_vap, p->p_ucred, p)) != 0) 355 goto bad; 356 if (vp->v_mount->mnt_flag & MNT_NOEXEC) { 357 error = EACCES; 358 goto bad; 359 } 360 if ((error = VOP_ACCESS(vp, VREAD, p->p_ucred, p)) != 0) 361 goto bad1; 362 if ((error = ELFNAME(read_from)(p, nd.ni_vp, 0, 363 (caddr_t)&eh, sizeof(eh))) != 0) 364 goto bad1; 365 366 if (ELFNAME(check_header)(&eh, ET_DYN) && 367 ELFNAME(olf_check_header)(&eh, ET_DYN, &os)) { 368 error = ENOEXEC; 369 goto bad1; 370 } 371 372 phsize = eh.e_phnum * sizeof(Elf_Phdr); 373 ph = (Elf_Phdr *)malloc(phsize, M_TEMP, M_WAITOK); 374 375 if ((error = ELFNAME(read_from)(p, nd.ni_vp, eh.e_phoff, (caddr_t)ph, 376 phsize)) != 0) 377 goto bad1; 378 379 /* 380 * Load all the necessary sections 381 */ 382 for (i = 0; i < eh.e_phnum; i++) { 383 Elf_Addr size = 0; 384 int prot = 0; 385 int flags; 386 387 switch (ph[i].p_type) { 388 case PT_LOAD: 389 if (base_ph == NULL) { 390 flags = VMCMD_BASE; 391 addr = *last; 392 base_ph = &ph[i]; 393 } else { 394 flags = VMCMD_RELATIVE; 395 addr = ph[i].p_vaddr - base_ph->p_vaddr; 396 } 397 ELFNAME(load_psection)(&epp->ep_vmcmds, nd.ni_vp, 398 &ph[i], &addr, &size, &prot, flags); 399 /* If entry is within this section it must be text */ 400 if (eh.e_entry >= ph[i].p_vaddr && 401 eh.e_entry < (ph[i].p_vaddr + size)) { 402 epp->ep_entry = addr + eh.e_entry - 403 ELF_TRUNC(ph[i].p_vaddr,ph[i].p_align); 404 ap->arg_interp = addr; 405 } 406 addr += size; 407 break; 408 409 case PT_DYNAMIC: 410 case PT_PHDR: 411 case PT_NOTE: 412 break; 413 414 default: 415 break; 416 } 417 } 418 419 vn_marktext(nd.ni_vp); 420 421 bad1: 422 VOP_CLOSE(nd.ni_vp, FREAD, p->p_ucred, p); 423 bad: 424 if (ph != NULL) 425 free((char *)ph, M_TEMP); 426 427 *last = addr; 428 vput(nd.ni_vp); 429 return (error); 430 } 431 432 /* 433 * Prepare an Elf binary's exec package 434 * 435 * First, set of the various offsets/lengths in the exec package. 436 * 437 * Then, mark the text image busy (so it can be demand paged) or error out if 438 * this is not possible. Finally, set up vmcmds for the text, data, bss, and 439 * stack segments. 440 */ 441 int 442 ELFNAME2(exec,makecmds)(struct proc *p, struct exec_package *epp) 443 { 444 Elf_Ehdr *eh = epp->ep_hdr; 445 Elf_Phdr *ph, *pp; 446 Elf_Addr phdr = 0; 447 int error, i; 448 char interp[MAXPATHLEN]; 449 u_long pos = 0, phsize; 450 u_int8_t os = OOS_NULL; 451 452 if (epp->ep_hdrvalid < sizeof(Elf_Ehdr)) 453 return (ENOEXEC); 454 455 if (ELFNAME(check_header)(eh, ET_EXEC) && 456 ELFNAME(olf_check_header)(eh, ET_EXEC, &os)) 457 return (ENOEXEC); 458 459 /* 460 * check if vnode is in open for writing, because we want to demand- 461 * page out of it. if it is, don't do it, for various reasons. 462 */ 463 if (epp->ep_vp->v_writecount != 0) { 464 #ifdef DIAGNOSTIC 465 if (epp->ep_vp->v_flag & VTEXT) 466 panic("exec: a VTEXT vnode has writecount != 0"); 467 #endif 468 return (ETXTBSY); 469 } 470 /* 471 * Allocate space to hold all the program headers, and read them 472 * from the file 473 */ 474 phsize = eh->e_phnum * sizeof(Elf_Phdr); 475 ph = (Elf_Phdr *)malloc(phsize, M_TEMP, M_WAITOK); 476 477 if ((error = ELFNAME(read_from)(p, epp->ep_vp, eh->e_phoff, (caddr_t)ph, 478 phsize)) != 0) 479 goto bad; 480 481 epp->ep_tsize = ELFDEFNNAME(NO_ADDR); 482 epp->ep_dsize = ELFDEFNNAME(NO_ADDR); 483 484 interp[0] = '\0'; 485 486 for (i = 0; i < eh->e_phnum; i++) { 487 pp = &ph[i]; 488 if (pp->p_type == PT_INTERP) { 489 if (pp->p_filesz >= sizeof(interp)) 490 goto bad; 491 if ((error = ELFNAME(read_from)(p, epp->ep_vp, 492 pp->p_offset, (caddr_t)interp, pp->p_filesz)) != 0) 493 goto bad; 494 break; 495 } 496 } 497 498 /* 499 * OK, we want a slightly different twist of the 500 * standard emulation package for "real" elf. 501 */ 502 epp->ep_emul = &ELFNAMEEND(emul); 503 pos = ELFDEFNNAME(NO_ADDR); 504 505 /* 506 * On the same architecture, we may be emulating different systems. 507 * See which one will accept this executable. 508 * 509 * Probe functions would normally see if the interpreter (if any) 510 * exists. Emulation packages may possibly replace the interpreter in 511 * interp[] with a changed path (/emul/xxx/<path>), and also 512 * set the ep_emul field in the exec package structure. 513 */ 514 error = ENOEXEC; 515 p->p_os = OOS_OPENBSD; 516 #ifdef NATIVE_EXEC_ELF 517 if (ELFNAME(os_pt_note)(p, epp, epp->ep_hdr, "OpenBSD", 8, 4) == 0) { 518 goto native; 519 } 520 #endif 521 for (i = 0; 522 i < sizeof(ELFNAME(probes)) / sizeof(ELFNAME(probes)[0]) && error; 523 i++) { 524 if (os == OOS_NULL || ((1 << os) & ELFNAME(probes)[i].os_mask)) 525 error = ELFNAME(probes)[i].func ? 526 (*ELFNAME(probes)[i].func)(p, epp, interp, &pos, &os) : 527 0; 528 } 529 if (!error) 530 p->p_os = os; 531 #ifndef NATIVE_EXEC_ELF 532 else 533 goto bad; 534 #else 535 native: 536 #endif /* NATIVE_EXEC_ELF */ 537 /* 538 * Load all the necessary sections 539 */ 540 for (i = 0; i < eh->e_phnum; i++) { 541 Elf_Addr addr = ELFDEFNNAME(NO_ADDR), size = 0; 542 int prot = 0; 543 544 pp = &ph[i]; 545 546 switch (ph[i].p_type) { 547 case PT_LOAD: 548 /* 549 * Calcuates size of text and data segments 550 * by starting at first and going to end of last. 551 * 'rwx' sections are treated as data. 552 * this is correct for BSS_PLT, but may not be 553 * for DATA_PLT, is fine for TEXT_PLT. 554 */ 555 ELFNAME(load_psection)(&epp->ep_vmcmds, epp->ep_vp, 556 &ph[i], &addr, &size, &prot, 0); 557 /* 558 * Decide whether it's text or data by looking 559 * at the protection of the section 560 */ 561 if (prot & VM_PROT_WRITE) { 562 /* data section */ 563 if (epp->ep_dsize == ELFDEFNNAME(NO_ADDR)) { 564 epp->ep_daddr = addr; 565 epp->ep_dsize = size; 566 } else { 567 if (addr < epp->ep_daddr) { 568 epp->ep_dsize = 569 epp->ep_dsize + 570 epp->ep_daddr - 571 addr; 572 epp->ep_daddr = addr; 573 } else 574 epp->ep_dsize = addr+size - 575 epp->ep_daddr; 576 } 577 } else if (prot & VM_PROT_EXECUTE) { 578 /* text section */ 579 if (epp->ep_tsize == ELFDEFNNAME(NO_ADDR)) { 580 epp->ep_taddr = addr; 581 epp->ep_tsize = size; 582 } else { 583 if (addr < epp->ep_taddr) { 584 epp->ep_tsize = 585 epp->ep_tsize + 586 epp->ep_taddr - 587 addr; 588 epp->ep_taddr = addr; 589 } else 590 epp->ep_tsize = addr+size - 591 epp->ep_taddr; 592 } 593 } 594 break; 595 596 case PT_SHLIB: 597 error = ENOEXEC; 598 goto bad; 599 600 case PT_INTERP: 601 /* Already did this one */ 602 case PT_DYNAMIC: 603 case PT_NOTE: 604 break; 605 606 case PT_PHDR: 607 /* Note address of program headers (in text segment) */ 608 phdr = pp->p_vaddr; 609 break; 610 611 default: 612 /* 613 * Not fatal, we don't need to understand everything 614 * :-) 615 */ 616 break; 617 } 618 } 619 620 #if !defined(__mips__) 621 /* 622 * If no position to load the interpreter was set by a probe 623 * function, pick the same address that a non-fixed mmap(0, ..) 624 * would (i.e. something safely out of the way). 625 */ 626 if (pos == ELFDEFNNAME(NO_ADDR)) 627 pos = round_page(epp->ep_daddr + MAXDSIZ); 628 #endif 629 630 /* 631 * Check if we found a dynamically linked binary and arrange to load 632 * it's interpreter when the exec file is released. 633 */ 634 if (interp[0]) { 635 char *ip; 636 struct elf_args *ap; 637 638 ip = (char *)malloc(MAXPATHLEN, M_TEMP, M_WAITOK); 639 ap = (struct elf_args *) 640 malloc(sizeof(struct elf_args), M_TEMP, M_WAITOK); 641 642 bcopy(interp, ip, MAXPATHLEN); 643 epp->ep_interp = ip; 644 epp->ep_interp_pos = pos; 645 646 ap->arg_phaddr = phdr; 647 ap->arg_phentsize = eh->e_phentsize; 648 ap->arg_phnum = eh->e_phnum; 649 ap->arg_entry = eh->e_entry; 650 ap->arg_os = os; 651 652 epp->ep_emul_arg = ap; 653 epp->ep_entry = eh->e_entry; /* keep check_exec() happy */ 654 } else { 655 epp->ep_interp = NULL; 656 epp->ep_entry = eh->e_entry; 657 } 658 659 #if defined(COMPAT_SVR4) && defined(i386) 660 #ifndef ELF_MAP_PAGE_ZERO 661 /* Dell SVR4 maps page zero, yeuch! */ 662 if (p->p_os == OOS_DELL) 663 #endif 664 NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_readvn, PAGE_SIZE, 0, 665 epp->ep_vp, 0, VM_PROT_READ); 666 #endif 667 668 free((char *)ph, M_TEMP); 669 vn_marktext(epp->ep_vp); 670 return (exec_setup_stack(p, epp)); 671 672 bad: 673 free((char *)ph, M_TEMP); 674 kill_vmcmds(&epp->ep_vmcmds); 675 return (ENOEXEC); 676 } 677 678 /* 679 * Phase II of load. It is now safe to load the interpreter. Info collected 680 * when loading the program is available for setup of the interpreter. 681 */ 682 int 683 ELFNAME2(exec,fixup)(struct proc *p, struct exec_package *epp) 684 { 685 char *interp; 686 int error; 687 struct elf_args *ap; 688 AuxInfo ai[ELF_AUX_ENTRIES], *a; 689 Elf_Addr pos = epp->ep_interp_pos; 690 691 if (epp->ep_interp == NULL) { 692 return (0); 693 } 694 695 interp = (char *)epp->ep_interp; 696 ap = (struct elf_args *)epp->ep_emul_arg; 697 698 if ((error = ELFNAME(load_file)(p, interp, epp, ap, &pos)) != 0) { 699 free((char *)ap, M_TEMP); 700 free((char *)interp, M_TEMP); 701 kill_vmcmds(&epp->ep_vmcmds); 702 return (error); 703 } 704 /* 705 * We have to do this ourselves... 706 */ 707 error = exec_process_vmcmds(p, epp); 708 709 /* 710 * Push extra arguments on the stack needed by dynamically 711 * linked binaries 712 */ 713 if (error == 0) { 714 a = ai; 715 716 a->au_id = AUX_phdr; 717 a->au_v = ap->arg_phaddr; 718 a++; 719 720 a->au_id = AUX_phent; 721 a->au_v = ap->arg_phentsize; 722 a++; 723 724 a->au_id = AUX_phnum; 725 a->au_v = ap->arg_phnum; 726 a++; 727 728 a->au_id = AUX_pagesz; 729 a->au_v = PAGE_SIZE; 730 a++; 731 732 a->au_id = AUX_base; 733 a->au_v = ap->arg_interp; 734 a++; 735 736 a->au_id = AUX_flags; 737 a->au_v = 0; 738 a++; 739 740 a->au_id = AUX_entry; 741 a->au_v = ap->arg_entry; 742 a++; 743 744 a->au_id = AUX_null; 745 a->au_v = 0; 746 a++; 747 748 error = copyout(ai, epp->ep_emul_argp, sizeof ai); 749 } 750 free((char *)ap, M_TEMP); 751 free((char *)interp, M_TEMP); 752 return (error); 753 } 754 755 char * 756 ELFNAME(check_brand)(Elf_Ehdr *eh) 757 { 758 if (eh->e_ident[EI_BRAND] == '\0') 759 return (NULL); 760 return (&eh->e_ident[EI_BRAND]); 761 } 762 763 int 764 ELFNAME(os_pt_note)(struct proc *p, struct exec_package *epp, Elf_Ehdr *eh, 765 char *os_name, size_t name_size, size_t desc_size) 766 { 767 Elf_Phdr *hph, *ph; 768 Elf_Note *np = NULL; 769 size_t phsize; 770 int error; 771 772 phsize = eh->e_phnum * sizeof(Elf_Phdr); 773 hph = (Elf_Phdr *)malloc(phsize, M_TEMP, M_WAITOK); 774 if ((error = ELFNAME(read_from)(p, epp->ep_vp, eh->e_phoff, 775 (caddr_t)hph, phsize)) != 0) 776 goto out1; 777 778 for (ph = hph; ph < &hph[eh->e_phnum]; ph++) { 779 if (ph->p_type != PT_NOTE || 780 ph->p_filesz < sizeof(Elf_Note) + name_size) 781 continue; 782 783 np = (Elf_Note *)malloc(ph->p_filesz, M_TEMP, M_WAITOK); 784 if ((error = ELFNAME(read_from)(p, epp->ep_vp, ph->p_offset, 785 (caddr_t)np, ph->p_filesz)) != 0) 786 goto out2; 787 788 #if 0 789 if (np->type != ELF_NOTE_TYPE_OSVERSION) { 790 free(np, M_TEMP); 791 np = NULL; 792 continue; 793 } 794 #endif 795 796 /* Check the name and description sizes. */ 797 if (np->namesz != name_size || 798 np->descsz != desc_size) 799 goto out3; 800 801 if (bcmp((np + 1), os_name, name_size)) 802 goto out3; 803 804 /* XXX: We could check for the specific emulation here */ 805 /* All checks succeeded. */ 806 error = 0; 807 goto out2; 808 } 809 810 out3: 811 error = ENOEXEC; 812 out2: 813 if (np) 814 free(np, M_TEMP); 815 out1: 816 free(hph, M_TEMP); 817 return error; 818 } 819