int ELFNAME2(linux32,probe)(struct lwp *l, struct exec_package *epp, void *eh, char *itp, vaddr_t *pos) { int error; if (((error = ELFNAME2(linux,signature)(l, epp, eh, itp)) != 0) && #ifdef LINUX32_GCC_SIGNATURE ((error = ELFNAME2(linux,gcc_signature)(l, epp, eh)) != 0) && #endif #ifdef LINUX32_ATEXIT_SIGNATURE ((error = ELFNAME2(linux,atexit_signature)(l, epp, eh)) != 0) && #endif #ifdef LINUX32_DEBUGLINK_SIGNATURE ((error = ELFNAME2(linux,debuglink_signature)(l, epp, eh)) != 0) && #endif 1) return error; if (itp) { if ((error = emul_find_interp(l, epp, itp))) return (error); } #if 0 DPRINTF(("linux32_probe: returning 0\n")); #endif epp->ep_flags |= EXEC_32 | EXEC_FORCEAUX; epp->ep_vm_minaddr = VM_MIN_ADDRESS; epp->ep_vm_maxaddr = USRSTACK32; return 0; }
int ELFNAME2(linux,probe)(struct lwp *l, struct exec_package *epp, void *eh, char *itp, vaddr_t *pos) { int error; if (((error = ELFNAME2(linux,signature)(l, epp, eh, itp)) != 0) && #ifdef LINUX_GCC_SIGNATURE ((error = ELFNAME2(linux,gcc_signature)(l, epp, eh)) != 0) && #endif #ifdef LINUX_ATEXIT_SIGNATURE ((error = ELFNAME2(linux,atexit_signature)(l, epp, eh)) != 0) && #endif #ifdef LINUX_DEBUGLINK_SIGNATURE ((error = ELFNAME2(linux,debuglink_signature)(l, epp, eh)) != 0) && #endif 1) { DPRINTF(("linux_probe: returning %d\n", error)); return error; } if (itp) { if ((error = emul_find_interp(l, epp, itp))) return (error); } epp->ep_flags |= EXEC_FORCEAUX; DPRINTF(("linux_probe: returning 0\n")); return 0; }
int svr4_elf64_probe(struct lwp *l, struct exec_package *epp, void *eh, char *itp, vaddr_t *pos) { int error; if (itp) { if ((error = emul_find_interp(l, epp, itp))) return error; } #ifdef SVR4_INTERP_ADDR *pos = SVR4_INTERP_ADDR; #endif return 0; }
int svr4_elf32_probe( struct lwp *l, struct exec_package *epp, void *eh, char *itp, vaddr_t *pos ) { struct proc *p = l->l_proc; int error; if (itp) { if ((error = emul_find_interp(LIST_FIRST(&p->p_lwps), epp, itp))) return error; } #ifdef SVR4_INTERP_ADDR *pos = SVR4_INTERP_ADDR; #endif return 0; }
static int osf1_exec_ecoff_dynamic(struct lwp *l, struct exec_package *epp) { struct osf1_exec_emul_arg *emul_arg = epp->ep_emul_arg; struct ecoff_exechdr ldr_exechdr; struct vnode *ldr_vp; size_t resid; int error; strncpy(emul_arg->loader_name, OSF1_LDR_EXEC_DEFAULT_LOADER, MAXPATHLEN + 1); /* * locate the loader * includes /emul/osf1 if appropriate */ error = emul_find_interp(LIST_FIRST(&l->l_proc->p_lwps), epp, emul_arg->loader_name); if (error) return error; emul_arg->flags |= OSF1_EXEC_EMUL_FLAGS_HAVE_LOADER; #if 0 uprintf("loader is %s\n", emul_arg->loader_name); #endif /* * open the loader, see if it's an ECOFF executable, * make sure the object type is amenable, then arrange to * load it up. */ ldr_vp = epp->ep_interp; epp->ep_interp = NULL; vn_lock(ldr_vp, LK_EXCLUSIVE | LK_RETRY); /* * Basic access checks. Reject if: * not a regular file * exec not allowed on binary * exec not allowed on mount point */ if (ldr_vp->v_type != VREG) { error = EACCES; goto badunlock; } if ((error = VOP_ACCESS(ldr_vp, VEXEC, l->l_cred)) != 0) goto badunlock; if (ldr_vp->v_mount->mnt_flag & MNT_NOEXEC) { error = EACCES; goto badunlock; } /* * If loader's mount point disallows set-id execution, * disable set-id. */ if (ldr_vp->v_mount->mnt_flag & MNT_NOSUID) epp->ep_vap->va_mode &= ~(S_ISUID | S_ISGID); VOP_UNLOCK(ldr_vp); /* * read the header, and make sure we got all of it. */ if ((error = vn_rdwr(UIO_READ, ldr_vp, (void *)&ldr_exechdr, sizeof ldr_exechdr, 0, UIO_SYSSPACE, 0, l->l_cred, &resid, NULL)) != 0) goto bad; if (resid != 0) { error = ENOEXEC; goto bad; } /* * Check the magic. We expect it to be the native Alpha ECOFF * (Digital UNIX) magic number. Also make sure it's not a shared * lib or dynamically linked executable. */ if (ldr_exechdr.f.f_magic != ECOFF_MAGIC_ALPHA) { error = ENOEXEC; goto bad; } switch (ldr_exechdr.f.f_flags & ECOFF_FLAG_OBJECT_TYPE_MASK) { case ECOFF_OBJECT_TYPE_SHARABLE: case ECOFF_OBJECT_TYPE_CALL_SHARED: /* can't exec shared lib or dynamically linked executable. */ error = ENOEXEC; goto bad; } switch (ldr_exechdr.a.magic) { case ECOFF_OMAGIC: error = exec_ecoff_prep_omagic(l, epp, &ldr_exechdr, ldr_vp); break; case ECOFF_NMAGIC: error = exec_ecoff_prep_nmagic(l, epp, &ldr_exechdr, ldr_vp); break; case ECOFF_ZMAGIC: error = exec_ecoff_prep_zmagic(l, epp, &ldr_exechdr, ldr_vp); break; default: error = ENOEXEC; } if (error) goto bad; /* finally, set up the stack. */ error = (*epp->ep_esch->es_setup_stack)(l, epp); if (error) goto bad; vrele(ldr_vp); return (0); badunlock: VOP_UNLOCK(ldr_vp); bad: vrele(ldr_vp); return (error); }
/* * load(mmap) file. for dynamic linker (ld.so.dll) */ int pecoff_load_file(struct lwp *l, struct exec_package *epp, const char *path, struct exec_vmcmd_set *vcset, u_long *entry, struct pecoff_args *argp) { int error, peofs, scnsiz, i; struct vnode *vp; struct vattr attr; struct pecoff_dos_filehdr dh; struct coff_filehdr *fp = 0; struct coff_aouthdr *ap; struct pecoff_opthdr *wp; struct coff_scnhdr *sh = 0; error = emul_find_interp(l, epp, path); if (error != 0) return error; vp = epp->ep_interp; epp->ep_interp = NULL; vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); /* * If it's not marked as executable, or it's not a regular * file, we don't allow it to be used. */ if (vp->v_type != VREG) { error = EACCES; goto badunlock; } if ((error = VOP_ACCESS(vp, VEXEC, l->l_cred)) != 0) goto badunlock; /* get attributes */ if ((error = VOP_GETATTR(vp, &attr, l->l_cred)) != 0) goto badunlock; /* * Check mount point. Though we're not trying to exec this binary, * we will be executing code from it, so if the mount point * disallows execution or set-id-ness, we punt or kill the set-id. */ if (vp->v_mount->mnt_flag & MNT_NOEXEC) { error = EACCES; goto badunlock; } if (vp->v_mount->mnt_flag & MNT_NOSUID) epp->ep_vap->va_mode &= ~(S_ISUID | S_ISGID); if ((error = vn_marktext(vp))) goto badunlock; VOP_UNLOCK(vp, 0); /* * Read header. */ error = exec_read_from(l, vp, 0, &dh, sizeof(dh)); if (error != 0) goto bad; if ((error = pecoff_signature(l, vp, &dh)) != 0) goto bad; fp = malloc(PECOFF_HDR_SIZE, M_TEMP, M_WAITOK); peofs = dh.d_peofs + sizeof(signature) - 1; error = exec_read_from(l, vp, peofs, fp, PECOFF_HDR_SIZE); if (error != 0) goto bad; if (COFF_BADMAG(fp)) { error = ENOEXEC; goto bad; } ap = (void *)((char *)fp + sizeof(struct coff_filehdr)); wp = (void *)((char *)ap + sizeof(struct coff_aouthdr)); /* read section header */ scnsiz = sizeof(struct coff_scnhdr) * fp->f_nscns; sh = malloc(scnsiz, M_TEMP, M_WAITOK); if ((error = exec_read_from(l, vp, peofs + PECOFF_HDR_SIZE, sh, scnsiz)) != 0) goto bad; /* * Read section header, and mmap. */ for (i = 0; i < fp->f_nscns; i++) { int prot = 0; long addr; u_long size; if (sh[i].s_flags & COFF_STYP_DISCARD) continue; /* XXX ? */ if ((sh[i].s_flags & COFF_STYP_TEXT) && (sh[i].s_flags & COFF_STYP_EXEC) == 0) continue; if ((sh[i].s_flags & (COFF_STYP_TEXT|COFF_STYP_DATA| COFF_STYP_BSS|COFF_STYP_READ)) == 0) continue; sh[i].s_vaddr += wp->w_base; /* RVA --> VA */ pecoff_load_section(vcset, vp, &sh[i], &addr, &size, &prot); } *entry = wp->w_base + ap->a_entry; argp->a_ldbase = wp->w_base; argp->a_ldexport = wp->w_imghdr[0].i_vaddr + wp->w_base; free(fp, M_TEMP); free(sh, M_TEMP); /*XXXUNCONST*/ vrele(vp); return 0; badunlock: VOP_UNLOCK(vp, 0); bad: if (fp != 0) free(fp, M_TEMP); if (sh != 0) free(sh, M_TEMP); /*XXXUNCONST*/ vrele(vp); return error; }