Пример #1
0
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;
}
Пример #3
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;
}
Пример #4
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);
}
Пример #6
0
/*
 * 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;
}