Home | History | Annotate | Line # | Download | only in common
linux_exec_elf32.c revision 1.100
      1  1.100        ad /*	$NetBSD: linux_exec_elf32.c,v 1.100 2020/01/12 18:30:58 ad Exp $	*/
      2   1.29  christos 
      3   1.29  christos /*-
      4   1.51      manu  * Copyright (c) 1995, 1998, 2000, 2001 The NetBSD Foundation, Inc.
      5   1.29  christos  * All rights reserved.
      6   1.29  christos  *
      7   1.29  christos  * This code is derived from software contributed to The NetBSD Foundation
      8   1.51      manu  * by Christos Zoulas, Frank van der Linden, Eric Haszlakiewicz and
      9   1.51      manu  * Emmanuel Dreyfus.
     10   1.29  christos  *
     11   1.29  christos  * Redistribution and use in source and binary forms, with or without
     12   1.29  christos  * modification, are permitted provided that the following conditions
     13   1.29  christos  * are met:
     14   1.29  christos  * 1. Redistributions of source code must retain the above copyright
     15   1.29  christos  *    notice, this list of conditions and the following disclaimer.
     16   1.29  christos  * 2. Redistributions in binary form must reproduce the above copyright
     17   1.29  christos  *    notice, this list of conditions and the following disclaimer in the
     18   1.29  christos  *    documentation and/or other materials provided with the distribution.
     19   1.29  christos  *
     20   1.29  christos  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     21   1.29  christos  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     22   1.29  christos  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     23   1.29  christos  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     24   1.29  christos  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     25   1.29  christos  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     26   1.29  christos  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     27   1.29  christos  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     28   1.29  christos  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     29   1.29  christos  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     30   1.29  christos  * POSSIBILITY OF SUCH DAMAGE.
     31   1.29  christos  */
     32    1.1      fvdl 
     33    1.1      fvdl /*
     34    1.7      fvdl  * based on exec_aout.c, sunos_exec.c and svr4_exec.c
     35    1.1      fvdl  */
     36   1.54     lukem 
     37   1.54     lukem #include <sys/cdefs.h>
     38  1.100        ad __KERNEL_RCSID(0, "$NetBSD: linux_exec_elf32.c,v 1.100 2020/01/12 18:30:58 ad Exp $");
     39    1.1      fvdl 
     40   1.31       erh #ifndef ELFSIZE
     41   1.58  christos /* XXX should die */
     42   1.58  christos #define	ELFSIZE		32
     43   1.31       erh #endif
     44   1.17       cgd 
     45    1.1      fvdl #include <sys/param.h>
     46    1.1      fvdl #include <sys/systm.h>
     47    1.1      fvdl #include <sys/kernel.h>
     48    1.1      fvdl #include <sys/proc.h>
     49    1.1      fvdl #include <sys/malloc.h>
     50    1.1      fvdl #include <sys/namei.h>
     51    1.1      fvdl #include <sys/vnode.h>
     52   1.13  christos #include <sys/mount.h>
     53   1.25  christos #include <sys/exec.h>
     54    1.8      fvdl #include <sys/exec_elf.h>
     55   1.59  jdolecek #include <sys/stat.h>
     56   1.72      elad #include <sys/kauth.h>
     57   1.88       chs #include <sys/cprng.h>
     58   1.98  pgoyette #include <sys/compat_stub.h>
     59    1.1      fvdl 
     60    1.1      fvdl #include <sys/mman.h>
     61   1.13  christos #include <sys/syscallargs.h>
     62    1.1      fvdl 
     63   1.80        ad #include <sys/cpu.h>
     64    1.1      fvdl #include <machine/reg.h>
     65    1.1      fvdl 
     66   1.32  christos #include <compat/linux/common/linux_types.h>
     67   1.32  christos #include <compat/linux/common/linux_signal.h>
     68   1.32  christos #include <compat/linux/common/linux_util.h>
     69   1.32  christos #include <compat/linux/common/linux_exec.h>
     70   1.32  christos #include <compat/linux/common/linux_machdep.h>
     71   1.82        ad #include <compat/linux/common/linux_ipc.h>
     72   1.82        ad #include <compat/linux/common/linux_sem.h>
     73   1.32  christos 
     74   1.32  christos #include <compat/linux/linux_syscallargs.h>
     75    1.4  christos #include <compat/linux/linux_syscall.h>
     76   1.31       erh 
     77   1.95  christos #define LINUX_GO_RT0_SIGNATURE
     78   1.95  christos 
     79   1.56  christos #ifdef DEBUG_LINUX
     80   1.56  christos #define DPRINTF(a)	uprintf a
     81   1.56  christos #else
     82   1.96   msaitoh #define DPRINTF(a)	do {} while (0)
     83   1.56  christos #endif
     84   1.56  christos 
     85   1.51      manu #ifdef LINUX_ATEXIT_SIGNATURE
     86   1.51      manu /*
     87   1.51      manu  * On the PowerPC, statically linked Linux binaries are not recognized
     88   1.51      manu  * by linux_signature nor by linux_gcc_signature. Fortunately, thoses
     89   1.51      manu  * binaries features a __libc_atexit ELF section. We therefore assume we
     90   1.51      manu  * have a Linux binary if we find this section.
     91   1.51      manu  */
     92   1.71      manu int
     93   1.86      matt ELFNAME2(linux,atexit_signature)(
     94   1.86      matt 	struct lwp *l,
     95   1.86      matt 	struct exec_package *epp,
     96   1.86      matt 	Elf_Ehdr *eh)
     97   1.51      manu {
     98   1.91      maxv 	Elf_Shdr *sh;
     99   1.51      manu 	size_t shsize;
    100   1.91      maxv 	u_int shstrndx;
    101   1.51      manu 	size_t i;
    102   1.51      manu 	static const char signature[] = "__libc_atexit";
    103   1.91      maxv 	const size_t sigsz = sizeof(signature);
    104   1.91      maxv 	char tbuf[sizeof(signature)];
    105   1.51      manu 	int error;
    106   1.51      manu 
    107   1.91      maxv 	/* Load the section header table. */
    108   1.51      manu 	shsize = eh->e_shnum * sizeof(Elf_Shdr);
    109   1.51      manu 	sh = (Elf_Shdr *) malloc(shsize, M_TEMP, M_WAITOK);
    110  1.100        ad 	error = exec_read(l, epp->ep_vp, eh->e_shoff, sh, shsize,
    111  1.100        ad 	    IO_NODELOCKED);
    112   1.51      manu 	if (error)
    113   1.51      manu 		goto out;
    114   1.51      manu 
    115   1.91      maxv 	/* Now let's find the string table. If it does not exist, give up. */
    116   1.91      maxv 	shstrndx = eh->e_shstrndx;
    117   1.91      maxv 	if (shstrndx == SHN_UNDEF || shstrndx >= eh->e_shnum) {
    118   1.51      manu 		error = ENOEXEC;
    119   1.51      manu 		goto out;
    120   1.51      manu 	}
    121   1.51      manu 
    122   1.91      maxv 	/* Check if any section has the name we're looking for. */
    123   1.91      maxv 	const off_t stroff = sh[shstrndx].sh_offset;
    124   1.51      manu 	for (i = 0; i < eh->e_shnum; i++) {
    125   1.51      manu 		Elf_Shdr *s = &sh[i];
    126   1.91      maxv 
    127   1.91      maxv 		if (s->sh_name + sigsz > sh[shstrndx].sh_size)
    128   1.91      maxv 			continue;
    129   1.91      maxv 
    130  1.100        ad 		error = exec_read(l, epp->ep_vp, stroff + s->sh_name, tbuf,
    131  1.100        ad 		    sigsz, IO_NODELOCKED);
    132   1.91      maxv 		if (error)
    133   1.91      maxv 			goto out;
    134   1.91      maxv 		if (!memcmp(tbuf, signature, sigsz)) {
    135   1.91      maxv 			DPRINTF(("linux_atexit_sig=%s\n", tbuf));
    136   1.51      manu 			error = 0;
    137   1.51      manu 			goto out;
    138   1.51      manu 		}
    139   1.51      manu 	}
    140   1.51      manu 	error = ENOEXEC;
    141   1.51      manu 
    142   1.51      manu out:
    143   1.51      manu 	free(sh, M_TEMP);
    144   1.51      manu 	return (error);
    145   1.51      manu }
    146   1.51      manu #endif
    147    1.4  christos 
    148   1.31       erh #ifdef LINUX_GCC_SIGNATURE
    149   1.14  christos /*
    150   1.14  christos  * Take advantage of the fact that all the linux binaries are compiled
    151   1.14  christos  * with gcc, and gcc sticks in the comment field a signature. Note that
    152   1.14  christos  * on SVR4 binaries, the gcc signature will follow the OS name signature,
    153   1.14  christos  * that will not be a problem. We don't bother to read in the string table,
    154   1.14  christos  * but we check all the progbits headers.
    155   1.31       erh  *
    156   1.31       erh  * XXX This only works in the i386.  On the alpha (at least)
    157   1.31       erh  * XXX we have the same gcc signature which incorrectly identifies
    158   1.31       erh  * XXX NetBSD binaries as Linux.
    159   1.14  christos  */
    160   1.71      manu int
    161   1.86      matt ELFNAME2(linux,gcc_signature)(
    162   1.86      matt 	struct lwp *l,
    163   1.86      matt 	struct exec_package *epp,
    164   1.86      matt 	Elf_Ehdr *eh)
    165   1.14  christos {
    166   1.50   mycroft 	size_t shsize;
    167   1.14  christos 	size_t i;
    168   1.14  christos 	static const char signature[] = "\0GCC: (GNU) ";
    169   1.69  christos 	char tbuf[sizeof(signature) - 1];
    170   1.31       erh 	Elf_Shdr *sh;
    171   1.14  christos 	int error;
    172   1.14  christos 
    173   1.50   mycroft 	shsize = eh->e_shnum * sizeof(Elf_Shdr);
    174   1.31       erh 	sh = (Elf_Shdr *) malloc(shsize, M_TEMP, M_WAITOK);
    175  1.100        ad 	error = exec_read(l, epp->ep_vp, eh->e_shoff, sh, shsize,
    176  1.100        ad 	    IO_NODELOCKED);
    177   1.50   mycroft 	if (error)
    178   1.14  christos 		goto out;
    179   1.14  christos 
    180   1.14  christos 	for (i = 0; i < eh->e_shnum; i++) {
    181   1.31       erh 		Elf_Shdr *s = &sh[i];
    182   1.14  christos 
    183   1.14  christos 		/*
    184   1.14  christos 		 * Identify candidates for the comment header;
    185   1.15  christos 		 * Header cannot have a load address, or flags and
    186   1.14  christos 		 * it must be large enough.
    187   1.14  christos 		 */
    188   1.43    kleink 		if (s->sh_type != SHT_PROGBITS ||
    189   1.14  christos 		    s->sh_addr != 0 ||
    190   1.14  christos 		    s->sh_flags != 0 ||
    191   1.14  christos 		    s->sh_size < sizeof(signature) - 1)
    192   1.14  christos 			continue;
    193   1.14  christos 
    194  1.100        ad 		error = exec_read(l, epp->ep_vp, s->sh_offset, tbuf,
    195  1.100        ad 		    sizeof(signature) - 1, IO_NODELOCKED);
    196   1.50   mycroft 		if (error)
    197   1.50   mycroft 			continue;
    198   1.14  christos 
    199   1.15  christos 		/*
    200   1.15  christos 		 * error is 0, if the signatures match we are done.
    201   1.15  christos 		 */
    202   1.69  christos 		DPRINTF(("linux_gcc_sig: sig=%s\n", tbuf));
    203   1.69  christos 		if (!memcmp(tbuf, signature, sizeof(signature) - 1)) {
    204   1.50   mycroft 			error = 0;
    205   1.14  christos 			goto out;
    206   1.50   mycroft 		}
    207   1.14  christos 	}
    208   1.50   mycroft 	error = ENOEXEC;
    209   1.14  christos 
    210   1.14  christos out:
    211   1.14  christos 	free(sh, M_TEMP);
    212   1.50   mycroft 	return (error);
    213   1.14  christos }
    214   1.31       erh #endif
    215   1.31       erh 
    216   1.74      manu #ifdef LINUX_DEBUGLINK_SIGNATURE
    217   1.74      manu /*
    218   1.91      maxv  * Look for a .gnu_debuglink, specific to x86_64 interpreter
    219   1.74      manu  */
    220   1.74      manu int
    221   1.83    cegger ELFNAME2(linux,debuglink_signature)(struct lwp *l, struct exec_package *epp, Elf_Ehdr *eh)
    222   1.74      manu {
    223   1.91      maxv 	Elf_Shdr *sh;
    224   1.74      manu 	size_t shsize;
    225   1.91      maxv 	u_int shstrndx;
    226   1.74      manu 	size_t i;
    227   1.74      manu 	static const char signature[] = ".gnu_debuglink";
    228   1.91      maxv 	const size_t sigsz = sizeof(signature);
    229   1.91      maxv 	char tbuf[sizeof(signature)];
    230   1.74      manu 	int error;
    231   1.74      manu 
    232   1.91      maxv 	/* Load the section header table. */
    233   1.74      manu 	shsize = eh->e_shnum * sizeof(Elf_Shdr);
    234   1.74      manu 	sh = (Elf_Shdr *) malloc(shsize, M_TEMP, M_WAITOK);
    235  1.100        ad 	error = exec_read(l, epp->ep_vp, eh->e_shoff, sh, shsize,
    236  1.100        ad 	    IO_NODELOCKED);
    237   1.74      manu 	if (error)
    238   1.74      manu 		goto out;
    239   1.74      manu 
    240   1.91      maxv 	/* Now let's find the string table. If it does not exist, give up. */
    241   1.91      maxv 	shstrndx = eh->e_shstrndx;
    242   1.91      maxv 	if (shstrndx == SHN_UNDEF || shstrndx >= eh->e_shnum) {
    243   1.74      manu 		error = ENOEXEC;
    244   1.74      manu 		goto out;
    245   1.74      manu 	}
    246   1.74      manu 
    247   1.91      maxv 	/* Check if any section has the name we're looking for. */
    248   1.91      maxv 	const off_t stroff = sh[shstrndx].sh_offset;
    249   1.74      manu 	for (i = 0; i < eh->e_shnum; i++) {
    250   1.74      manu 		Elf_Shdr *s = &sh[i];
    251   1.74      manu 
    252   1.91      maxv 		if (s->sh_name + sigsz > sh[shstrndx].sh_size)
    253   1.91      maxv 			continue;
    254   1.91      maxv 
    255  1.100        ad 		error = exec_read(l, epp->ep_vp, stroff + s->sh_name, tbuf,
    256  1.100        ad 		    sigsz, IO_NODELOCKED);
    257   1.91      maxv 		if (error)
    258   1.91      maxv 			goto out;
    259   1.91      maxv 		if (!memcmp(tbuf, signature, sigsz)) {
    260   1.91      maxv 			DPRINTF(("linux_debuglink_sig=%s\n", tbuf));
    261   1.74      manu 			error = 0;
    262   1.74      manu 			goto out;
    263   1.74      manu 		}
    264   1.74      manu 	}
    265   1.74      manu 	error = ENOEXEC;
    266   1.74      manu 
    267   1.74      manu out:
    268   1.74      manu 	free(sh, M_TEMP);
    269   1.74      manu 	return (error);
    270   1.74      manu }
    271   1.74      manu #endif
    272   1.74      manu 
    273   1.95  christos #ifdef LINUX_GO_RT0_SIGNATURE
    274   1.95  christos /*
    275   1.95  christos  * Look for a .gopclntab, specific to go binaries
    276   1.95  christos  * in it look for a symbol called _rt0_<cpu>_linux
    277   1.95  christos  */
    278   1.95  christos static int
    279   1.95  christos ELFNAME2(linux,go_rt0_signature)(struct lwp *l, struct exec_package *epp, Elf_Ehdr *eh)
    280   1.95  christos {
    281   1.95  christos 	Elf_Shdr *sh;
    282   1.95  christos 	size_t shsize;
    283   1.95  christos 	u_int shstrndx;
    284   1.95  christos 	size_t i;
    285   1.95  christos 	static const char signature[] = ".gopclntab";
    286   1.95  christos 	const size_t sigsz = sizeof(signature);
    287   1.95  christos 	char tbuf[sizeof(signature)], *tmp = NULL;
    288   1.95  christos 	char mbuf[64];
    289   1.95  christos 	const char *m;
    290   1.95  christos 	int mlen;
    291   1.95  christos 	int error;
    292   1.95  christos 
    293   1.95  christos 	/* Load the section header table. */
    294   1.95  christos 	shsize = eh->e_shnum * sizeof(Elf_Shdr);
    295   1.95  christos 	sh = malloc(shsize, M_TEMP, M_WAITOK);
    296  1.100        ad 	error = exec_read(l, epp->ep_vp, eh->e_shoff, sh, shsize,
    297  1.100        ad 	    IO_NODELOCKED);
    298   1.95  christos 	if (error)
    299   1.95  christos 		goto out;
    300   1.95  christos 
    301   1.95  christos 	/* Now let's find the string table. If it does not exist, give up. */
    302   1.95  christos 	shstrndx = eh->e_shstrndx;
    303   1.95  christos 	if (shstrndx == SHN_UNDEF || shstrndx >= eh->e_shnum) {
    304   1.95  christos 		error = ENOEXEC;
    305   1.95  christos 		goto out;
    306   1.95  christos 	}
    307   1.95  christos 
    308   1.95  christos 	/* Check if any section has the name we're looking for. */
    309   1.95  christos 	const off_t stroff = sh[shstrndx].sh_offset;
    310   1.95  christos 	for (i = 0; i < eh->e_shnum; i++) {
    311   1.95  christos 		Elf_Shdr *s = &sh[i];
    312   1.95  christos 
    313   1.95  christos 		if (s->sh_name + sigsz > sh[shstrndx].sh_size)
    314   1.95  christos 			continue;
    315   1.95  christos 
    316  1.100        ad 		error = exec_read(l, epp->ep_vp, stroff + s->sh_name, tbuf,
    317  1.100        ad 		    sigsz, IO_NODELOCKED);
    318   1.95  christos 		if (error)
    319   1.95  christos 			goto out;
    320   1.95  christos 		if (!memcmp(tbuf, signature, sigsz)) {
    321   1.96   msaitoh 			DPRINTF(("linux_goplcntab_sig=%s\n", tbuf));
    322   1.95  christos 			break;
    323   1.95  christos 		}
    324   1.95  christos 	}
    325   1.95  christos 
    326   1.95  christos 	if (i == eh->e_shnum) {
    327   1.95  christos 		error = ENOEXEC;
    328   1.95  christos 		goto out;
    329   1.95  christos 	}
    330   1.95  christos 
    331   1.97  christos 	// Don't scan more than 1MB
    332   1.97  christos 	if (sh[i].sh_size > 1024 * 1024)
    333   1.97  christos 		sh[i].sh_size = 1024 * 1024;
    334   1.95  christos 
    335   1.95  christos 	tmp = malloc(sh[i].sh_size, M_TEMP, M_WAITOK);
    336  1.100        ad 	error = exec_read(l, epp->ep_vp, sh[i].sh_offset, tmp,
    337  1.100        ad 	    sh[i].sh_size, IO_NODELOCKED);
    338   1.95  christos 	if (error)
    339   1.95  christos 		goto out;
    340   1.95  christos 
    341   1.95  christos #if (ELFSIZE == 32)
    342   1.98  pgoyette 	extern struct netbsd32_machine32_hook_t netbsd32_machine32_hook;
    343   1.99  pgoyette 	MODULE_HOOK_CALL(netbsd32_machine32_hook, (), machine, m);
    344   1.95  christos #else
    345   1.95  christos 	m = machine;
    346   1.95  christos #endif
    347   1.95  christos 	mlen = snprintf(mbuf, sizeof(mbuf), "_rt0_%s_linux", m);
    348   1.95  christos 	if (memmem(tmp, sh[i].sh_size, mbuf, mlen) == NULL)
    349   1.95  christos 		error = ENOEXEC;
    350   1.95  christos 	else
    351   1.95  christos 		DPRINTF(("linux_rt0_sig=%s\n", mbuf));
    352   1.95  christos out:
    353   1.95  christos 	if (tmp)
    354   1.95  christos 		free(tmp, M_TEMP);
    355   1.95  christos 	free(sh, M_TEMP);
    356   1.95  christos 	return error;
    357   1.95  christos }
    358   1.95  christos #endif
    359   1.95  christos 
    360   1.71      manu int
    361   1.83    cegger ELFNAME2(linux,signature)(struct lwp *l, struct exec_package *epp, Elf_Ehdr *eh, char *itp)
    362   1.31       erh {
    363   1.31       erh 	size_t i;
    364   1.31       erh 	Elf_Phdr *ph;
    365   1.31       erh 	size_t phsize;
    366   1.50   mycroft 	int error;
    367   1.57  christos 	static const char linux[] = "Linux";
    368   1.57  christos 
    369   1.94       uwe 	if (eh->e_ident[EI_OSABI] == ELFOSABI_LINUX ||
    370   1.57  christos 	    memcmp(&eh->e_ident[EI_ABIVERSION], linux, sizeof(linux)) == 0)
    371   1.57  christos 		return 0;
    372   1.31       erh 
    373   1.31       erh 	phsize = eh->e_phnum * sizeof(Elf_Phdr);
    374   1.31       erh 	ph = (Elf_Phdr *)malloc(phsize, M_TEMP, M_WAITOK);
    375  1.100        ad 	error = exec_read(l, epp->ep_vp, eh->e_phoff, ph, phsize,
    376  1.100        ad 	    IO_NODELOCKED);
    377   1.50   mycroft 	if (error)
    378   1.50   mycroft 		goto out;
    379   1.31       erh 
    380   1.31       erh 	for (i = 0; i < eh->e_phnum; i++) {
    381   1.31       erh 		Elf_Phdr *ephp = &ph[i];
    382   1.50   mycroft 		Elf_Nhdr *np;
    383   1.50   mycroft 		u_int32_t *abi;
    384   1.31       erh 
    385   1.50   mycroft 		if (ephp->p_type != PT_NOTE ||
    386   1.50   mycroft 		    ephp->p_filesz > 1024 ||
    387   1.50   mycroft 		    ephp->p_filesz < sizeof(Elf_Nhdr) + 20)
    388   1.31       erh 			continue;
    389   1.31       erh 
    390   1.50   mycroft 		np = (Elf_Nhdr *)malloc(ephp->p_filesz, M_TEMP, M_WAITOK);
    391  1.100        ad 		error = exec_read(l, epp->ep_vp, ephp->p_offset, np,
    392  1.100        ad 		    ephp->p_filesz, IO_NODELOCKED);
    393   1.50   mycroft 		if (error)
    394   1.50   mycroft 			goto next;
    395   1.50   mycroft 
    396   1.50   mycroft 		if (np->n_type != ELF_NOTE_TYPE_ABI_TAG ||
    397   1.50   mycroft 		    np->n_namesz != ELF_NOTE_ABI_NAMESZ ||
    398   1.50   mycroft 		    np->n_descsz != ELF_NOTE_ABI_DESCSZ ||
    399   1.78  christos 		    memcmp((void *)(np + 1), ELF_NOTE_ABI_NAME,
    400   1.50   mycroft 		    ELF_NOTE_ABI_NAMESZ))
    401   1.50   mycroft 			goto next;
    402   1.50   mycroft 
    403   1.50   mycroft 		/* Make sure the OS is Linux. */
    404   1.78  christos 		abi = (u_int32_t *)((char *)np + sizeof(Elf_Nhdr) +
    405   1.50   mycroft 		    np->n_namesz);
    406   1.50   mycroft 		if (abi[0] == ELF_NOTE_ABI_OS_LINUX)
    407   1.50   mycroft 			error = 0;
    408   1.50   mycroft 		else
    409   1.40       erh 			error = ENOEXEC;
    410   1.50   mycroft 		free(np, M_TEMP);
    411   1.50   mycroft 		goto out;
    412   1.31       erh 
    413   1.50   mycroft 	next:
    414   1.50   mycroft 		free(np, M_TEMP);
    415   1.50   mycroft 		continue;
    416   1.50   mycroft 	}
    417   1.31       erh 
    418   1.91      maxv 	/* Check for certain interpreter names. */
    419   1.66  drochner 	if (itp) {
    420   1.50   mycroft 		if (!strncmp(itp, "/lib/ld-linux", 13) ||
    421   1.68      manu #if (ELFSIZE == 64)
    422   1.68      manu 		    !strncmp(itp, "/lib64/ld-linux", 15) ||
    423   1.68      manu #endif
    424   1.50   mycroft 		    !strncmp(itp, "/lib/ld.so.", 11))
    425   1.50   mycroft 			error = 0;
    426   1.50   mycroft 		else
    427   1.50   mycroft 			error = ENOEXEC;
    428   1.50   mycroft 		goto out;
    429   1.31       erh 	}
    430   1.31       erh 
    431   1.31       erh 	error = ENOEXEC;
    432   1.50   mycroft out:
    433   1.31       erh 	free(ph, M_TEMP);
    434   1.50   mycroft 	return (error);
    435   1.31       erh }
    436   1.14  christos 
    437    1.8      fvdl int
    438   1.75  christos ELFNAME2(linux,probe)(struct lwp *l, struct exec_package *epp, void *eh,
    439   1.76  christos     char *itp, vaddr_t *pos)
    440    1.6      fvdl {
    441    1.8      fvdl 	int error;
    442   1.14  christos 
    443   1.70  christos 	if (((error = ELFNAME2(linux,signature)(l, epp, eh, itp)) != 0) &&
    444   1.51      manu #ifdef LINUX_GCC_SIGNATURE
    445   1.70  christos 	    ((error = ELFNAME2(linux,gcc_signature)(l, epp, eh)) != 0) &&
    446   1.53      manu #endif
    447   1.51      manu #ifdef LINUX_ATEXIT_SIGNATURE
    448   1.70  christos 	    ((error = ELFNAME2(linux,atexit_signature)(l, epp, eh)) != 0) &&
    449   1.53      manu #endif
    450   1.74      manu #ifdef LINUX_DEBUGLINK_SIGNATURE
    451   1.74      manu 	    ((error = ELFNAME2(linux,debuglink_signature)(l, epp, eh)) != 0) &&
    452   1.74      manu #endif
    453   1.95  christos #ifdef LINUX_GO_RT0_SIGNATURE
    454   1.95  christos 	    ((error = ELFNAME2(linux,go_rt0_signature)(l, epp, eh)) != 0) &&
    455   1.95  christos #endif
    456   1.74      manu 	    1) {
    457   1.74      manu 			DPRINTF(("linux_probe: returning %d\n", error));
    458   1.51      manu 			return error;
    459   1.74      manu 	}
    460    1.6      fvdl 
    461   1.66  drochner 	if (itp) {
    462   1.79       dsl 		if ((error = emul_find_interp(l, epp, itp)))
    463   1.60  jdolecek 			return (error);
    464    1.6      fvdl 	}
    465   1.84       chs 	epp->ep_flags |= EXEC_FORCEAUX;
    466   1.56  christos 	DPRINTF(("linux_probe: returning 0\n"));
    467    1.6      fvdl 	return 0;
    468    1.6      fvdl }
    469    1.6      fvdl 
    470   1.59  jdolecek #ifndef LINUX_MACHDEP_ELF_COPYARGS
    471   1.59  jdolecek /*
    472   1.59  jdolecek  * Copy arguments onto the stack in the normal way, but add some
    473   1.59  jdolecek  * extra information in case of dynamic binding.
    474   1.59  jdolecek  */
    475   1.59  jdolecek int
    476   1.70  christos ELFNAME2(linux,copyargs)(struct lwp *l, struct exec_package *pack,
    477   1.59  jdolecek     struct ps_strings *arginfo, char **stackp, void *argp)
    478   1.59  jdolecek {
    479   1.59  jdolecek 	size_t len;
    480   1.59  jdolecek 	AuxInfo ai[LINUX_ELF_AUX_ENTRIES], *a;
    481   1.59  jdolecek 	struct elf_args *ap;
    482   1.59  jdolecek 	int error;
    483   1.59  jdolecek 	struct vattr *vap;
    484   1.87       chs 	uint32_t randbytes[4];
    485   1.59  jdolecek 
    486   1.70  christos 	if ((error = copyargs(l, pack, arginfo, stackp, argp)) != 0)
    487   1.59  jdolecek 		return error;
    488   1.59  jdolecek 
    489   1.59  jdolecek 	a = ai;
    490   1.59  jdolecek 
    491   1.92      maxv 	memset(ai, 0, sizeof(ai));
    492   1.92      maxv 
    493   1.59  jdolecek 	/*
    494   1.59  jdolecek 	 * Push extra arguments used by glibc on the stack.
    495   1.59  jdolecek 	 */
    496   1.59  jdolecek 
    497   1.59  jdolecek 	a->a_type = AT_PAGESZ;
    498   1.59  jdolecek 	a->a_v = PAGE_SIZE;
    499   1.59  jdolecek 	a++;
    500   1.59  jdolecek 
    501   1.59  jdolecek 	if ((ap = (struct elf_args *)pack->ep_emul_arg)) {
    502   1.59  jdolecek 
    503   1.59  jdolecek 		a->a_type = AT_PHDR;
    504   1.59  jdolecek 		a->a_v = ap->arg_phaddr;
    505   1.59  jdolecek 		a++;
    506   1.59  jdolecek 
    507   1.59  jdolecek 		a->a_type = AT_PHENT;
    508   1.59  jdolecek 		a->a_v = ap->arg_phentsize;
    509   1.59  jdolecek 		a++;
    510   1.59  jdolecek 
    511   1.59  jdolecek 		a->a_type = AT_PHNUM;
    512   1.59  jdolecek 		a->a_v = ap->arg_phnum;
    513   1.59  jdolecek 		a++;
    514   1.59  jdolecek 
    515   1.59  jdolecek 		a->a_type = AT_BASE;
    516   1.59  jdolecek 		a->a_v = ap->arg_interp;
    517   1.59  jdolecek 		a++;
    518   1.59  jdolecek 
    519   1.59  jdolecek 		a->a_type = AT_FLAGS;
    520   1.59  jdolecek 		a->a_v = 0;
    521   1.59  jdolecek 		a++;
    522   1.59  jdolecek 
    523   1.59  jdolecek 		a->a_type = AT_ENTRY;
    524   1.59  jdolecek 		a->a_v = ap->arg_entry;
    525   1.59  jdolecek 		a++;
    526   1.59  jdolecek 
    527   1.85      matt 		exec_free_emul_arg(pack);
    528   1.59  jdolecek 	}
    529   1.59  jdolecek 
    530   1.59  jdolecek 	/* Linux-specific items */
    531   1.59  jdolecek 	a->a_type = LINUX_AT_CLKTCK;
    532   1.59  jdolecek 	a->a_v = hz;
    533   1.59  jdolecek 	a++;
    534   1.59  jdolecek 
    535   1.59  jdolecek 	vap = pack->ep_vap;
    536   1.59  jdolecek 
    537   1.59  jdolecek 	a->a_type = LINUX_AT_UID;
    538   1.73        ad 	a->a_v = kauth_cred_getuid(l->l_cred);
    539   1.59  jdolecek 	a++;
    540   1.59  jdolecek 
    541   1.59  jdolecek 	a->a_type = LINUX_AT_EUID;
    542   1.59  jdolecek 	if (vap->va_mode & S_ISUID)
    543   1.59  jdolecek 		a->a_v = vap->va_uid;
    544   1.59  jdolecek 	else
    545   1.73        ad 		a->a_v = kauth_cred_geteuid(l->l_cred);
    546   1.59  jdolecek 	a++;
    547   1.59  jdolecek 
    548   1.59  jdolecek 	a->a_type = LINUX_AT_GID;
    549   1.73        ad 	a->a_v = kauth_cred_getgid(l->l_cred);
    550   1.59  jdolecek 	a++;
    551   1.59  jdolecek 
    552   1.59  jdolecek 	a->a_type = LINUX_AT_EGID;
    553   1.59  jdolecek 	if (vap->va_mode & S_ISGID)
    554   1.59  jdolecek 		a->a_v = vap->va_gid;
    555   1.59  jdolecek 	else
    556   1.73        ad 		a->a_v = kauth_cred_getegid(l->l_cred);
    557   1.59  jdolecek 	a++;
    558   1.59  jdolecek 
    559   1.87       chs 	a->a_type = LINUX_AT_RANDOM;
    560   1.93      matt 	a->a_v = (Elf_Addr)(uintptr_t)*stackp;
    561   1.87       chs 	a++;
    562   1.87       chs 
    563   1.59  jdolecek 	a->a_type = AT_NULL;
    564   1.59  jdolecek 	a->a_v = 0;
    565   1.59  jdolecek 	a++;
    566   1.59  jdolecek 
    567   1.88       chs 	randbytes[0] = cprng_strong32();
    568   1.88       chs 	randbytes[1] = cprng_strong32();
    569   1.88       chs 	randbytes[2] = cprng_strong32();
    570   1.88       chs 	randbytes[3] = cprng_strong32();
    571   1.87       chs 
    572   1.87       chs 	len = sizeof(randbytes);
    573   1.87       chs 	if ((error = copyout(randbytes, *stackp, len)) != 0)
    574   1.87       chs 		return error;
    575   1.87       chs 	*stackp += len;
    576   1.87       chs 
    577   1.59  jdolecek 	len = (a - ai) * sizeof(AuxInfo);
    578   1.90     njoly 	KASSERT(len <= LINUX_ELF_AUX_ENTRIES * sizeof(AuxInfo));
    579   1.59  jdolecek 	if ((error = copyout(ai, *stackp, len)) != 0)
    580   1.59  jdolecek 		return error;
    581   1.59  jdolecek 	*stackp += len;
    582   1.59  jdolecek 
    583   1.59  jdolecek 	return 0;
    584   1.59  jdolecek }
    585   1.59  jdolecek #endif /* !LINUX_MACHDEP_ELF_COPYARGS */
    586