/*
 * copy arguments onto the stack in the normal way, then copy out
 * any ELF-like AUX entries used by the dynamic loading scheme.
 */
int
osf1_copyargs(struct lwp *l, struct exec_package *pack, struct ps_strings *arginfo, char **stackp, void *argp)
{
	struct osf1_exec_emul_arg *emul_arg = pack->ep_emul_arg;
	struct osf1_auxv ai[OSF1_MAX_AUX_ENTRIES], *a;
	char *prognameloc, *loadernameloc;
	size_t len;
	int error;

	if ((error = copyargs(l, pack, arginfo, stackp, argp)) != 0)
		goto out;

	a = ai;
	memset(ai, 0, sizeof ai);

	prognameloc = *stackp + sizeof ai;
	if ((error = copyoutstr(emul_arg->exec_name, prognameloc,
	    MAXPATHLEN + 1, NULL)) != 0)
	    goto out;
	a->a_type = OSF1_AT_EXEC_FILENAME;
	a->a_un.a_ptr = prognameloc;
	a++;

	/*
	 * if there's a loader, push additional auxv entries on the stack.
	 */
	if (emul_arg->flags & OSF1_EXEC_EMUL_FLAGS_HAVE_LOADER) {

		loadernameloc = prognameloc + MAXPATHLEN + 1;
		if ((error = copyoutstr(emul_arg->loader_name, loadernameloc,
		    MAXPATHLEN + 1, NULL)) != 0)
			goto out;
		a->a_type = OSF1_AT_EXEC_LOADER_FILENAME;
		a->a_un.a_ptr = loadernameloc;
		a++;

		a->a_type = OSF1_AT_EXEC_LOADER_FLAGS;
		a->a_un.a_val = 0;
                if (pack->ep_vap->va_mode & S_ISUID)
                        a->a_un.a_val |= OSF1_LDR_EXEC_SETUID_F;
                if (pack->ep_vap->va_mode & S_ISGID)
                        a->a_un.a_val |= OSF1_LDR_EXEC_SETGID_F;
	        if (l->l_proc->p_slflag & PSL_TRACED)
                        a->a_un.a_val |= OSF1_LDR_EXEC_PTRACE_F;
		a++;
	}

	a->a_type = OSF1_AT_NULL;
	a->a_un.a_val = 0;
	a++;

	len = (a - ai) * sizeof(struct osf1_auxv);
	if ((error = copyout(ai, *stackp, len)) != 0)
		goto out;
	*stackp += len;

out:
	exec_free_emul_arg(pack);
	return error;
}
int
osf1_exec_ecoff_probe(struct lwp *l, struct exec_package *epp)
{
        struct ecoff_exechdr *execp = (struct ecoff_exechdr *)epp->ep_hdr;
	struct osf1_exec_emul_arg *emul_arg;
	int error;

	/* check if the binary is osf1 ecoff */
	if (execp->f.f_magic != ECOFF_MAGIC_ALPHA)
		return ENOEXEC;

	/* set up the exec package emul arg as appropriate */
	emul_arg = kmem_alloc(sizeof(*emul_arg), KM_SLEEP);
	epp->ep_emul_arg = emul_arg;
	epp->ep_emul_arg_free = osf1_free_emul_arg;

	emul_arg->flags = 0;
	/* this cannot overflow because both are size PATH_MAX */
	strcpy(emul_arg->exec_name, epp->ep_kname);

	/* do any special object file handling */
	switch (execp->f.f_flags & ECOFF_FLAG_OBJECT_TYPE_MASK) {
	case ECOFF_OBJECT_TYPE_SHARABLE:
		/* can't exec a shared library! */
#if 0
		uprintf("can't execute OSF/1 shared libraries\n");
#endif
		error = ENOEXEC;
		break;

	case ECOFF_OBJECT_TYPE_CALL_SHARED:
		error = osf1_exec_ecoff_dynamic(l, epp);
		break;

	default:
		/* just let the normal ECOFF handlers deal with it. */
		error = 0;
		break;
	}

	if (error) {
		exec_free_emul_arg(epp);
		kill_vmcmds(&epp->ep_vmcmds);		/* if any */
	}

	return (error);
}
Example #3
0
/*
 * Copy arguments onto the stack in the normal way, but add some
 * extra information in case of dynamic binding.
 */
int
linux32_elf32_copyargs(struct lwp *l, struct exec_package *pack,
    struct ps_strings *arginfo, char **stackp, void *argp)
{
	Aux32Info ai[LINUX32_ELF_AUX_ENTRIES], *a;
	uint32_t randbytes[4];
	struct elf_args *ap;
	struct vattr *vap;
	size_t len;
	int error;

	if ((error = netbsd32_copyargs(l, pack, arginfo, stackp, argp)) != 0)
		return error;

	a = ai;

	memset(ai, 0, sizeof(ai));

	/*
	 * Push extra arguments on the stack needed by dynamically
	 * linked binaries and static binaries as well.
	 */

	a->a_type = AT_PAGESZ;
	a->a_v = PAGE_SIZE;
	a++;

	if ((ap = (struct elf_args *)pack->ep_emul_arg)) {

		a->a_type = AT_PHDR;
		a->a_v = ap->arg_phaddr;
		a++;

		a->a_type = AT_PHENT;
		a->a_v = ap->arg_phentsize;
		a++;

		a->a_type = AT_PHNUM;
		a->a_v = ap->arg_phnum;
		a++;

		a->a_type = AT_BASE;
		a->a_v = ap->arg_interp;
		a++;

		a->a_type = AT_FLAGS;
		a->a_v = 0;
		a++;

		a->a_type = AT_ENTRY;
		a->a_v = ap->arg_entry;
		a++;

		exec_free_emul_arg(pack);
	}

	/* Linux-specific items */
	a->a_type = LINUX_AT_CLKTCK;
	a->a_v = hz;
	a++;

	vap = pack->ep_vap;

	a->a_type = LINUX_AT_UID;
	a->a_v = kauth_cred_getuid(l->l_cred);
	a++;

	a->a_type = LINUX_AT_EUID;
	a->a_v = ((vap->va_mode & S_ISUID) ?
	    vap->va_uid : kauth_cred_geteuid(l->l_cred));
	a++;

	a->a_type = LINUX_AT_GID;
	a->a_v = kauth_cred_getgid(l->l_cred);
	a++;

	a->a_type = LINUX_AT_EGID;
	a->a_v = ((vap->va_mode & S_ISGID) ?
	    vap->va_gid : kauth_cred_getegid(l->l_cred));
	a++;

	a->a_type = LINUX_AT_SECURE;
	a->a_v = 0;
	a++;

	a->a_type = LINUX_AT_RANDOM;
	a->a_v = NETBSD32PTR32I(*stackp);
	a++;

#if 0
	/* XXX: increase LINUX32_ELF_AUX_ENTRIES if we enable those things */

	a->a_type = LINUX_AT_SYSINFO;
	a->a_v = NETBSD32PTR32I(&esdp->kernel_vsyscall[0]);
	a++;

	a->a_type = LINUX_AT_SYSINFO_EHDR;
	a->a_v = NETBSD32PTR32I(&esdp->elfhdr);
	a++;

	a->a_type = LINUX_AT_HWCAP;
	a->a_v = LINUX32_CPUCAP;
	a++;

	a->a_type = LINUX_AT_PLATFORM;
	a->a_v = NETBSD32PTR32I(&esdp->hw_platform[0]);
	a++;
#endif

	a->a_type = AT_NULL;
	a->a_v = 0;
	a++;

	randbytes[0] = cprng_strong32();
	randbytes[1] = cprng_strong32();
	randbytes[2] = cprng_strong32();
	randbytes[3] = cprng_strong32();

	len = sizeof(randbytes);
	if ((error = copyout(randbytes, *stackp, len)) != 0)
		return error;
	*stackp += len;

#if 0
	memcpy(esd.kernel_vsyscall, linux32_kernel_vsyscall,
	    sizeof(linux32_kernel_vsyscall));

	memcpy(&esd.elfhdr, eh, sizeof(*eh));

	strcpy(esd.hw_platform, LINUX32_PLATFORM);
	
	/*
	 * Copy out the ELF auxiliary table and hw platform name
	 */
	if ((error = copyout(&esd, esdp, sizeof(esd))) != 0)
		return error;
	*stackp += sizeof(esd);
#endif

	len = (a - ai) * sizeof(Aux32Info);
	KASSERT(len <= LINUX32_ELF_AUX_ENTRIES * sizeof(Aux32Info));
	if ((error = copyout(ai, *stackp, len)) != 0)
		return error;
	*stackp += len;

	return 0;
}
Example #4
0
int
svr4_32_copyargs(struct lwp *l, struct exec_package *pack, struct ps_strings *arginfo, char **stackp, void *argp)
{
	size_t len;
	AuxInfo ai[SVR4_32_AUX_ARGSIZ], *a, *platform=NULL, *exec=NULL;
	struct elf_args *ap;
	extern char machine_model[];
	int error;

	if ((error = netbsd32_copyargs(l, pack, arginfo, stackp, argp)) != 0)
		return error;

	a = ai;

	memset(ai, 0, sizeof(ai));

	/*
	 * Push extra arguments on the stack needed by dynamically
	 * linked binaries
	 */
	if ((ap = (struct elf_args *)pack->ep_emul_arg)) {
		struct proc *p = curproc; /* XXXXX */

		a->a_type = AT_SUN_PLATFORM;
		platform = a; /* Patch this later. */
		a++;

		a->a_type = AT_SUN_EXECNAME;
		exec = a; /* Patch this later. */
		a++;

		a->a_type = AT_PHDR;
		a->a_v = ap->arg_phaddr;
		a++;

		a->a_type = AT_PHENT;
		a->a_v = ap->arg_phentsize;
		a++;

		a->a_type = AT_PHNUM;
		a->a_v = ap->arg_phnum;
		a++;

		a->a_type = AT_ENTRY;
		a->a_v = ap->arg_entry;
		a++;

		a->a_type = AT_BASE;
		a->a_v = ap->arg_interp;
		a++;

		if (sun_flags) {
			a->a_type = AT_FLAGS;
			a->a_v = sun_flags;
			a++;
		}

		a->a_type = AT_PAGESZ;
		a->a_v = PAGE_SIZE;
		a++;

		a->a_type = AT_EUID;
		a->a_v = kauth_cred_geteuid(l->l_cred);
		a++;

		a->a_type = AT_RUID;
		a->a_v = kauth_cred_getuid(l->l_cred);
		a++;

		a->a_type = AT_EGID;
		a->a_v = kauth_cred_getegid(l->l_cred);
		a++;

		a->a_type = AT_RGID;
		a->a_v = kauth_cred_getgid(l->l_cred);
		a++;

		if (sun_hwcap) {
			a->a_type = AT_SUN_HWCAP;
			a->a_v = sun_hwcap;
			a++;
		}

		exec_free_emul_arg(pack);
	}

	a->a_type = AT_NULL;
	a->a_v = 0;
	a++;

	len = (a - ai) * sizeof(AuxInfo);

	if (platform) {
		char *ptr = (char *)a;
		const char *path = NULL;

		/* Copy out the platform name. */
		platform->a_v = (u_long)(*stackp) + len;
		/* XXXX extremely inefficient.... */
		strcpy(ptr, machine_model);
		ptr += strlen(machine_model) + 1;
		len += strlen(machine_model) + 1;

		if (exec) {
			path = pack->ep_resolvedname;

			/* Copy out the file we're executing. */
			exec->a_v = (u_long)(*stackp) + len;
			strcpy(ptr, path);
			len += strlen(ptr)+1;
		}

		/* Round to 32-bits */
		len = (len+7)&~0x7L;
	}
	if ((error = copyout(ai, *stackp, len)) != 0)
		return error;
	*stackp += len;

	return error;
}
Example #5
0
int
svr4_32_copyargs(struct lwp *l, struct exec_package *pack, struct ps_strings *arginfo, char **stackp, void *argp)
{
	size_t len;
	AuxInfo ai[SVR4_32_AUX_ARGSIZ], *a;
	struct elf_args *ap;
	int error;

	if ((error = netbsd32_copyargs(l, pack, arginfo, stackp, argp)) != 0)
		return error;

	a = ai;

	memset(ai, 0, sizeof(ai));

	/*
	 * Push extra arguments on the stack needed by dynamically
	 * linked binaries
	 */
	if ((ap = (struct elf_args *)pack->ep_emul_arg)) {

		a->a_type = AT_PHDR;
		a->a_v = ap->arg_phaddr;
		a++;

		a->a_type = AT_PHENT;
		a->a_v = ap->arg_phentsize;
		a++;

		a->a_type = AT_PHNUM;
		a->a_v = ap->arg_phnum;
		a++;

		a->a_type = AT_PAGESZ;
		a->a_v = PAGE_SIZE;
		a++;

		a->a_type = AT_BASE;
		a->a_v = ap->arg_interp;
		a++;

		a->a_type = AT_ENTRY;
		a->a_v = ap->arg_entry;
		a++;

		if (sun_flags) {
			a->a_type = AT_FLAGS;
			a->a_v = sun_flags;
			a++;
		}

		exec_free_emul_arg(pack);
	}

	a->a_type = AT_NULL;
	a->a_v = 0;
	a++;

	len = (a - ai) * sizeof(AuxInfo);
	if ((error = copyout(ai, *stackp, len)) != 0)
		return error;
	*stackp += len;

	return 0;
}
int
ELFNAME2(linux,copyargs)(struct lwp *l, struct exec_package *pack,
	struct ps_strings *arginfo, char **stackp, void *argp)
{
	struct linux_extra_stack_data64 *esdp, esd;
	struct elf_args *ap;
	struct vattr *vap;
	Elf_Ehdr *eh;
	Elf_Phdr *ph;
	u_long phsize;
	Elf_Addr phdr = 0;
	int error;
	int i;

	if ((error = copyargs(l, pack, arginfo, stackp, argp)) != 0)
		return error;

	/*
	 * Push extra arguments on the stack needed by dynamically
	 * linked binaries and static binaries as well.
	 */
	memset(&esd, 0, sizeof(esd));
	esdp = (struct linux_extra_stack_data64 *)(*stackp);
	ap = (struct elf_args *)pack->ep_emul_arg;
	vap = pack->ep_vap;
	eh = (Elf_Ehdr *)pack->ep_hdr;

	/*
	 * We forgot this, so we need to reload it now. XXX keep track of it?
	 */
	if (ap == NULL) {
		phsize = eh->e_phnum * sizeof(Elf_Phdr);
		ph = (Elf_Phdr *)kmem_alloc(phsize, KM_SLEEP);
		error = exec_read_from(l, pack->ep_vp, eh->e_phoff, ph, phsize);
		if (error != 0) {
			for (i = 0; i < eh->e_phnum; i++) {
				if (ph[i].p_type == PT_PHDR) {
					phdr = ph[i].p_vaddr;
					break;
				}
			}
		}
		kmem_free(ph, phsize);
	}


	/*
	 * The exec_package doesn't have a proc pointer and it's not
	 * exactly trivial to add one since the credentials are
	 * changing. XXX Linux uses curlwp's credentials.
	 * Why can't we use them too?
	 */

	i = 0;
	esd.ai[i].a_type = LINUX_AT_HWCAP;
	esd.ai[i++].a_v = rcr4();

	esd.ai[i].a_type = AT_PAGESZ;
	esd.ai[i++].a_v = PAGE_SIZE;

	esd.ai[i].a_type = LINUX_AT_CLKTCK;
	esd.ai[i++].a_v = hz;

	esd.ai[i].a_type = AT_PHDR;
	esd.ai[i++].a_v = (ap ? ap->arg_phaddr: phdr);

	esd.ai[i].a_type = AT_PHENT;
	esd.ai[i++].a_v = (ap ? ap->arg_phentsize : eh->e_phentsize);

	esd.ai[i].a_type = AT_PHNUM;
	esd.ai[i++].a_v = (ap ? ap->arg_phnum : eh->e_phnum);

	esd.ai[i].a_type = AT_BASE;
	esd.ai[i++].a_v = (ap ? ap->arg_interp : 0);

	esd.ai[i].a_type = AT_FLAGS;
	esd.ai[i++].a_v = 0;

	esd.ai[i].a_type = AT_ENTRY;
	esd.ai[i++].a_v = (ap ? ap->arg_entry : eh->e_entry);

	esd.ai[i].a_type = LINUX_AT_EGID;
	esd.ai[i++].a_v = ((vap->va_mode & S_ISGID) ?
	    vap->va_gid : kauth_cred_getegid(l->l_cred));

	esd.ai[i].a_type = LINUX_AT_GID;
	esd.ai[i++].a_v = kauth_cred_getgid(l->l_cred);

	esd.ai[i].a_type = LINUX_AT_EUID;
	esd.ai[i++].a_v = ((vap->va_mode & S_ISUID) ? 
	    vap->va_uid : kauth_cred_geteuid(l->l_cred));

	esd.ai[i].a_type = LINUX_AT_UID;
	esd.ai[i++].a_v = kauth_cred_getuid(l->l_cred);

	esd.ai[i].a_type = LINUX_AT_SECURE;
	esd.ai[i++].a_v = 0;

	esd.ai[i].a_type = LINUX_AT_PLATFORM;
	esd.ai[i++].a_v = (Elf_Addr)&esdp->hw_platform[0];

	esd.ai[i].a_type = AT_NULL;
	esd.ai[i++].a_v = 0;

#ifdef DEBUG_LINUX
	if (i != LINUX_ELF_AUX_ENTRIES) {
		printf("linux_elf64_copyargs: %d Aux entries\n", i);
		return EINVAL;
	}
#endif
		
	strcpy(esd.hw_platform, LINUX_PLATFORM); 

	exec_free_emul_arg(pack);

	/*
	 * Copy out the ELF auxiliary table and hw platform name
	 */
	if ((error = copyout(&esd, esdp, sizeof(esd))) != 0)
		return error;
	*stackp += sizeof(esd);

	return 0;
}
/*
 * Copy arguments onto the stack in the normal way, but add some
 * extra information in case of dynamic binding.
 */
int
netbsd32_elf32_copyargs(struct lwp *l, struct exec_package *pack,
    struct ps_strings *arginfo, char **stackp, void *argp)
{
	size_t len;
	AuxInfo ai[ELF_AUX_ENTRIES], *a;
	struct elf_args *ap;
	int error;

	if ((error = netbsd32_copyargs(l, pack, arginfo, stackp, argp)) != 0)
		return error;

	a = ai;

	/*
	 * Push extra arguments on the stack needed by dynamically
	 * linked binaries
	 */
	if ((ap = (struct elf_args *)pack->ep_emul_arg)) {

		a->a_type = AT_PHDR;
		a->a_v = ap->arg_phaddr;
		a++;

		a->a_type = AT_PHENT;
		a->a_v = ap->arg_phentsize;
		a++;

		a->a_type = AT_PHNUM;
		a->a_v = ap->arg_phnum;
		a++;

		a->a_type = AT_PAGESZ;
		a->a_v = PAGE_SIZE;
		a++;

		a->a_type = AT_BASE;
		a->a_v = ap->arg_interp;
		a++;

		a->a_type = AT_FLAGS;
		a->a_v = 0;
		a++;

		a->a_type = AT_ENTRY;
		a->a_v = ap->arg_entry;
		a++;

		a->a_type = AT_EUID;
		a->a_v = kauth_cred_geteuid(l->l_cred);
		a++;

		a->a_type = AT_RUID;
		a->a_v = kauth_cred_getuid(l->l_cred);
		a++;

		a->a_type = AT_EGID;
		a->a_v = kauth_cred_getegid(l->l_cred);
		a++;

		a->a_type = AT_RGID;
		a->a_v = kauth_cred_getgid(l->l_cred);
		a++;

		exec_free_emul_arg(pack);
	}

	a->a_type = AT_NULL;
	a->a_v = 0;
	a++;

	len = (a - ai) * sizeof(AuxInfo);
	if ((error = copyout(ai, *stackp, len)) != 0)
		return error;
	*stackp += len;

	return 0;
}
/*
 * Copy arguments onto the stack in the normal way, but add some
 * extra information in case of dynamic binding.
 */
int
ELFNAME2(linux,copyargs)(struct lwp *l, struct exec_package *pack,
                         struct ps_strings *arginfo, char **stackp, void *argp)
{
    size_t len;
    AuxInfo ai[LINUX_ELF_AUX_ENTRIES], *a;
    struct elf_args *ap;
    int error;
    struct vattr *vap;

    if ((error = copyargs(l, pack, arginfo, stackp, argp)) != 0)
        return error;

    a = ai;

    /*
     * Push extra arguments used by glibc on the stack.
     */

    a->a_type = AT_PAGESZ;
    a->a_v = PAGE_SIZE;
    a++;

    if ((ap = (struct elf_args *)pack->ep_emul_arg)) {

        a->a_type = AT_PHDR;
        a->a_v = ap->arg_phaddr;
        a++;

        a->a_type = AT_PHENT;
        a->a_v = ap->arg_phentsize;
        a++;

        a->a_type = AT_PHNUM;
        a->a_v = ap->arg_phnum;
        a++;

        a->a_type = AT_BASE;
        a->a_v = ap->arg_interp;
        a++;

        a->a_type = AT_FLAGS;
        a->a_v = 0;
        a++;

        a->a_type = AT_ENTRY;
        a->a_v = ap->arg_entry;
        a++;

        exec_free_emul_arg(pack);
    }

    /* Linux-specific items */
    a->a_type = LINUX_AT_CLKTCK;
    a->a_v = hz;
    a++;

    vap = pack->ep_vap;

    a->a_type = LINUX_AT_UID;
    a->a_v = kauth_cred_getuid(l->l_cred);
    a++;

    a->a_type = LINUX_AT_EUID;
    if (vap->va_mode & S_ISUID)
        a->a_v = vap->va_uid;
    else
        a->a_v = kauth_cred_geteuid(l->l_cred);
    a++;

    a->a_type = LINUX_AT_GID;
    a->a_v = kauth_cred_getgid(l->l_cred);
    a++;

    a->a_type = LINUX_AT_EGID;
    if (vap->va_mode & S_ISGID)
        a->a_v = vap->va_gid;
    else
        a->a_v = kauth_cred_getegid(l->l_cred);
    a++;

    a->a_type = AT_NULL;
    a->a_v = 0;
    a++;

    len = (a - ai) * sizeof(AuxInfo);
    if ((error = copyout(ai, *stackp, len)) != 0)
        return error;
    *stackp += len;

    return 0;
}