1 /* $OpenBSD: exec_elf.c,v 1.37 2001/11/15 06:22:30 art 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) __P((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 *); 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) 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_ROUND(*addr, ph->p_align); 254 uaddr = ELF_TRUNC(ph->p_vaddr, ph->p_align); 255 } else 256 uaddr = ph->p_vaddr; 257 diff = ph->p_vaddr - uaddr; 258 } else { 259 *addr = uaddr = ph->p_vaddr; 260 if (ph->p_align > 1) 261 *addr = ELF_TRUNC(uaddr, ph->p_align); 262 diff = uaddr - *addr; 263 } 264 265 *prot |= (ph->p_flags & PF_R) ? VM_PROT_READ : 0; 266 *prot |= (ph->p_flags & PF_W) ? VM_PROT_WRITE : 0; 267 *prot |= (ph->p_flags & PF_X) ? VM_PROT_EXECUTE : 0; 268 269 offset = ph->p_offset - diff; 270 *size = ph->p_filesz + diff; 271 msize = ph->p_memsz + diff; 272 psize = round_page(*size); 273 274 /* 275 * Because the pagedvn pager can't handle zero fill of the last 276 * data page if it's not page aligned we map the last page readvn. 277 */ 278 if (ph->p_flags & PF_W) { 279 psize = trunc_page(*size); 280 NEW_VMCMD(vcset, vmcmd_map_pagedvn, psize, *addr, vp, 281 offset, *prot); 282 if (psize != *size) { 283 NEW_VMCMD(vcset, vmcmd_map_readvn, *size - psize, 284 *addr + psize, vp, offset + psize, *prot); 285 } 286 } else { 287 NEW_VMCMD(vcset, vmcmd_map_pagedvn, psize, *addr, vp, offset, 288 *prot); 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_VMCMD(vcset, vmcmd_map_zero, rm - rf, rf, NULLVP, 0, 299 *prot); 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 IO_NODELOCKED, 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 = *last; 340 struct vnode *vp; 341 u_int8_t os; /* Just a dummy in this routine */ 342 343 bp = path; 344 NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_SYSSPACE, path, p); 345 if ((error = namei(&nd)) != 0) { 346 return (error); 347 } 348 vp = nd.ni_vp; 349 if (vp->v_type != VREG) { 350 error = EACCES; 351 goto bad; 352 } 353 if ((error = VOP_GETATTR(vp, epp->ep_vap, p->p_ucred, p)) != 0) 354 goto bad; 355 if (vp->v_mount->mnt_flag & MNT_NOEXEC) { 356 error = EACCES; 357 goto bad; 358 } 359 if ((error = VOP_ACCESS(vp, VREAD, p->p_ucred, p)) != 0) 360 goto bad1; 361 if ((error = ELFNAME(read_from)(p, nd.ni_vp, 0, 362 (caddr_t)&eh, sizeof(eh))) != 0) 363 goto bad1; 364 365 if (ELFNAME(check_header)(&eh, ET_DYN) && 366 ELFNAME(olf_check_header)(&eh, ET_DYN, &os)) { 367 error = ENOEXEC; 368 goto bad1; 369 } 370 371 phsize = eh.e_phnum * sizeof(Elf_Phdr); 372 ph = (Elf_Phdr *)malloc(phsize, M_TEMP, M_WAITOK); 373 374 if ((error = ELFNAME(read_from)(p, nd.ni_vp, eh.e_phoff, (caddr_t)ph, 375 phsize)) != 0) 376 goto bad1; 377 378 /* 379 * Load all the necessary sections 380 */ 381 for (i = 0; i < eh.e_phnum; i++) { 382 Elf_Addr size = 0; 383 int prot = 0; 384 #if defined(__mips__) 385 if (*last == ELFDEFNNAME(NO_ADDR)) 386 addr = ELFDEFNNAME(NO_ADDR); /* GRRRRR!!!!! */ 387 #endif 388 389 switch (ph[i].p_type) { 390 case PT_LOAD: 391 ELFNAME(load_psection)(&epp->ep_vmcmds, nd.ni_vp, 392 &ph[i], &addr, &size, &prot); 393 /* If entry is within this section it must be text */ 394 if (eh.e_entry >= ph[i].p_vaddr && 395 eh.e_entry < (ph[i].p_vaddr + size)) { 396 epp->ep_entry = addr + eh.e_entry - 397 ELF_TRUNC(ph[i].p_vaddr,ph[i].p_align); 398 ap->arg_interp = addr; 399 } 400 addr += size; 401 break; 402 403 case PT_DYNAMIC: 404 case PT_PHDR: 405 case PT_NOTE: 406 break; 407 408 default: 409 break; 410 } 411 } 412 413 bad1: 414 VOP_CLOSE(nd.ni_vp, FREAD, p->p_ucred, p); 415 bad: 416 if (ph != NULL) 417 free((char *)ph, M_TEMP); 418 419 *last = addr; 420 vput(nd.ni_vp); 421 return (error); 422 } 423 424 /* 425 * Prepare an Elf binary's exec package 426 * 427 * First, set of the various offsets/lengths in the exec package. 428 * 429 * Then, mark the text image busy (so it can be demand paged) or error out if 430 * this is not possible. Finally, set up vmcmds for the text, data, bss, and 431 * stack segments. 432 */ 433 int 434 ELFNAME2(exec,makecmds)(struct proc *p, struct exec_package *epp) 435 { 436 Elf_Ehdr *eh = epp->ep_hdr; 437 Elf_Phdr *ph, *pp; 438 Elf_Addr phdr = 0; 439 int error, i, nload; 440 char interp[MAXPATHLEN]; 441 u_long pos = 0, phsize; 442 u_int8_t os = OOS_NULL; 443 444 if (epp->ep_hdrvalid < sizeof(Elf_Ehdr)) 445 return (ENOEXEC); 446 447 if (ELFNAME(check_header)(eh, ET_EXEC) && 448 ELFNAME(olf_check_header)(eh, ET_EXEC, &os)) 449 return (ENOEXEC); 450 451 /* 452 * check if vnode is in open for writing, because we want to demand- 453 * page out of it. if it is, don't do it, for various reasons. 454 */ 455 if (epp->ep_vp->v_writecount != 0) { 456 #ifdef DIAGNOSTIC 457 if (epp->ep_vp->v_flag & VTEXT) 458 panic("exec: a VTEXT vnode has writecount != 0"); 459 #endif 460 return (ETXTBSY); 461 } 462 /* 463 * Allocate space to hold all the program headers, and read them 464 * from the file 465 */ 466 phsize = eh->e_phnum * sizeof(Elf_Phdr); 467 ph = (Elf_Phdr *)malloc(phsize, M_TEMP, M_WAITOK); 468 469 if ((error = ELFNAME(read_from)(p, epp->ep_vp, eh->e_phoff, (caddr_t)ph, 470 phsize)) != 0) 471 goto bad; 472 473 epp->ep_tsize = ELFDEFNNAME(NO_ADDR); 474 epp->ep_dsize = ELFDEFNNAME(NO_ADDR); 475 476 interp[0] = '\0'; 477 478 for (i = 0; i < eh->e_phnum; i++) { 479 pp = &ph[i]; 480 if (pp->p_type == PT_INTERP) { 481 if (pp->p_filesz >= sizeof(interp)) 482 goto bad; 483 if ((error = ELFNAME(read_from)(p, epp->ep_vp, 484 pp->p_offset, (caddr_t)interp, pp->p_filesz)) != 0) 485 goto bad; 486 break; 487 } 488 } 489 490 /* 491 * OK, we want a slightly different twist of the 492 * standard emulation package for "real" elf. 493 */ 494 epp->ep_emul = &ELFNAMEEND(emul); 495 pos = ELFDEFNNAME(NO_ADDR); 496 497 /* 498 * On the same architecture, we may be emulating different systems. 499 * See which one will accept this executable. 500 * 501 * Probe functions would normally see if the interpreter (if any) 502 * exists. Emulation packages may possibly replace the interpreter in 503 * interp[] with a changed path (/emul/xxx/<path>), and also 504 * set the ep_emul field in the exec package structure. 505 */ 506 error = ENOEXEC; 507 p->p_os = OOS_OPENBSD; 508 #ifdef NATIVE_EXEC_ELF 509 if (ELFNAME(os_pt_note)(p, epp, epp->ep_hdr, "OpenBSD", 8, 4) == 0) { 510 goto native; 511 } 512 #endif 513 for (i = 0; 514 i < sizeof(ELFNAME(probes)) / sizeof(ELFNAME(probes)[0]) && error; 515 i++) { 516 if (os == OOS_NULL || ((1 << os) & ELFNAME(probes)[i].os_mask)) 517 error = ELFNAME(probes)[i].func ? 518 (*ELFNAME(probes)[i].func)(p, epp, interp, &pos, &os) : 519 0; 520 } 521 if (!error) 522 p->p_os = os; 523 #ifndef NATIVE_EXEC_ELF 524 else 525 goto bad; 526 #else 527 native: 528 #endif /* NATIVE_EXEC_ELF */ 529 /* 530 * Load all the necessary sections 531 */ 532 for (i = nload = 0; i < eh->e_phnum; i++) { 533 Elf_Addr addr = ELFDEFNNAME(NO_ADDR), size = 0; 534 int prot = 0; 535 536 pp = &ph[i]; 537 538 switch (ph[i].p_type) { 539 case PT_LOAD: 540 /* 541 * XXX 542 * Can handle only 2 sections: text and data 543 */ 544 if (nload++ == 2) 545 goto bad; 546 ELFNAME(load_psection)(&epp->ep_vmcmds, epp->ep_vp, 547 &ph[i], &addr, &size, &prot); 548 /* 549 * Decide whether it's text or data by looking 550 * at the entry point. 551 */ 552 if (eh->e_entry >= addr && 553 eh->e_entry < (addr + size)) { 554 epp->ep_taddr = addr; 555 epp->ep_tsize = size; 556 if (epp->ep_daddr == ELFDEFNNAME(NO_ADDR)) { 557 epp->ep_daddr = addr; 558 epp->ep_dsize = size; 559 } 560 } else { 561 epp->ep_daddr = addr; 562 epp->ep_dsize = size; 563 } 564 break; 565 566 case PT_SHLIB: 567 error = ENOEXEC; 568 goto bad; 569 570 case PT_INTERP: 571 /* Already did this one */ 572 case PT_DYNAMIC: 573 case PT_NOTE: 574 break; 575 576 case PT_PHDR: 577 /* Note address of program headers (in text segment) */ 578 phdr = pp->p_vaddr; 579 break; 580 581 default: 582 /* 583 * Not fatal, we don't need to understand everything 584 * :-) 585 */ 586 break; 587 } 588 } 589 590 #if !defined(__mips__) 591 /* 592 * If no position to load the interpreter was set by a probe 593 * function, pick the same address that a non-fixed mmap(0, ..) 594 * would (i.e. something safely out of the way). 595 */ 596 if (pos == ELFDEFNNAME(NO_ADDR)) 597 pos = round_page(epp->ep_daddr + MAXDSIZ); 598 #endif 599 600 /* 601 * Check if we found a dynamically linked binary and arrange to load 602 * it's interpreter when the exec file is released. 603 */ 604 if (interp[0]) { 605 char *ip; 606 struct elf_args *ap; 607 608 ip = (char *)malloc(MAXPATHLEN, M_TEMP, M_WAITOK); 609 ap = (struct elf_args *) 610 malloc(sizeof(struct elf_args), M_TEMP, M_WAITOK); 611 612 bcopy(interp, ip, MAXPATHLEN); 613 epp->ep_interp = ip; 614 epp->ep_interp_pos = pos; 615 616 ap->arg_phaddr = phdr; 617 ap->arg_phentsize = eh->e_phentsize; 618 ap->arg_phnum = eh->e_phnum; 619 ap->arg_entry = eh->e_entry; 620 ap->arg_os = os; 621 622 epp->ep_emul_arg = ap; 623 epp->ep_entry = eh->e_entry; /* keep check_exec() happy */ 624 } else { 625 epp->ep_interp = NULL; 626 epp->ep_entry = eh->e_entry; 627 } 628 629 #if defined(COMPAT_SVR4) && defined(i386) 630 #ifndef ELF_MAP_PAGE_ZERO 631 /* Dell SVR4 maps page zero, yeuch! */ 632 if (p->p_os == OOS_DELL) 633 #endif 634 NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_readvn, PAGE_SIZE, 0, 635 epp->ep_vp, 0, VM_PROT_READ); 636 #endif 637 638 free((char *)ph, M_TEMP); 639 vn_marktext(epp->ep_vp); 640 return (exec_setup_stack(p, epp)); 641 642 bad: 643 free((char *)ph, M_TEMP); 644 kill_vmcmds(&epp->ep_vmcmds); 645 return (ENOEXEC); 646 } 647 648 /* 649 * Phase II of load. It is now safe to load the interpreter. Info collected 650 * when loading the program is available for setup of the interpreter. 651 */ 652 int 653 ELFNAME2(exec,fixup)(struct proc *p, struct exec_package *epp) 654 { 655 char *interp; 656 int error, i; 657 struct elf_args *ap; 658 AuxInfo ai[ELF_AUX_ENTRIES], *a; 659 Elf_Addr pos = epp->ep_interp_pos; 660 661 if (epp->ep_interp == 0) { 662 return (0); 663 } 664 665 interp = (char *)epp->ep_interp; 666 ap = (struct elf_args *)epp->ep_emul_arg; 667 668 if ((error = ELFNAME(load_file)(p, interp, epp, ap, &pos)) != 0) { 669 free((char *)ap, M_TEMP); 670 free((char *)interp, M_TEMP); 671 kill_vmcmds(&epp->ep_vmcmds); 672 return (error); 673 } 674 /* 675 * We have to do this ourselves... 676 */ 677 for (i = 0; i < epp->ep_vmcmds.evs_used && !error; i++) { 678 struct exec_vmcmd *vcp; 679 680 vcp = &epp->ep_vmcmds.evs_cmds[i]; 681 error = (*vcp->ev_proc)(p, vcp); 682 } 683 kill_vmcmds(&epp->ep_vmcmds); 684 685 /* 686 * Push extra arguments on the stack needed by dynamically 687 * linked binaries 688 */ 689 if (error == 0) { 690 a = ai; 691 692 a->au_id = AUX_phdr; 693 a->au_v = ap->arg_phaddr; 694 a++; 695 696 a->au_id = AUX_phent; 697 a->au_v = ap->arg_phentsize; 698 a++; 699 700 a->au_id = AUX_phnum; 701 a->au_v = ap->arg_phnum; 702 a++; 703 704 a->au_id = AUX_pagesz; 705 a->au_v = PAGE_SIZE; 706 a++; 707 708 a->au_id = AUX_base; 709 a->au_v = ap->arg_interp; 710 a++; 711 712 a->au_id = AUX_flags; 713 a->au_v = 0; 714 a++; 715 716 a->au_id = AUX_entry; 717 a->au_v = ap->arg_entry; 718 a++; 719 720 a->au_id = AUX_null; 721 a->au_v = 0; 722 a++; 723 724 error = copyout(ai, epp->ep_emul_argp, sizeof ai); 725 } 726 free((char *)ap, M_TEMP); 727 free((char *)interp, M_TEMP); 728 return (error); 729 } 730 731 char * 732 ELFNAME(check_brand)(Elf_Ehdr *eh) 733 { 734 if (eh->e_ident[EI_BRAND] == '\0') 735 return (NULL); 736 return (&eh->e_ident[EI_BRAND]); 737 } 738 739 int 740 ELFNAME(os_pt_note)(struct proc *p, struct exec_package *epp, Elf_Ehdr *eh, 741 char *os_name, size_t name_size, size_t desc_size) 742 { 743 Elf_Phdr *hph, *ph; 744 Elf_Note *np = NULL; 745 size_t phsize; 746 int error; 747 748 phsize = eh->e_phnum * sizeof(Elf_Phdr); 749 hph = (Elf_Phdr *)malloc(phsize, M_TEMP, M_WAITOK); 750 if ((error = ELFNAME(read_from)(p, epp->ep_vp, eh->e_phoff, 751 (caddr_t)hph, phsize)) != 0) 752 goto out1; 753 754 for (ph = hph; ph < &hph[eh->e_phnum]; ph++) { 755 if (ph->p_type != PT_NOTE || 756 ph->p_filesz < sizeof(Elf_Note) + name_size) 757 continue; 758 759 np = (Elf_Note *)malloc(ph->p_filesz, M_TEMP, M_WAITOK); 760 if ((error = ELFNAME(read_from)(p, epp->ep_vp, ph->p_offset, 761 (caddr_t)np, ph->p_filesz)) != 0) 762 goto out2; 763 764 #if 0 765 if (np->type != ELF_NOTE_TYPE_OSVERSION) { 766 free(np, M_TEMP); 767 np = NULL; 768 continue; 769 } 770 #endif 771 772 /* Check the name and description sizes. */ 773 if (np->namesz != name_size || 774 np->descsz != desc_size) 775 goto out3; 776 777 if (bcmp((np + 1), os_name, name_size)) 778 goto out3; 779 780 /* XXX: We could check for the specific emulation here */ 781 /* All checks succeeded. */ 782 error = 0; 783 goto out2; 784 } 785 786 out3: 787 error = ENOEXEC; 788 out2: 789 if (np) 790 free(np, M_TEMP); 791 out1: 792 free(hph, M_TEMP); 793 return error; 794 } 795