Home | History | Annotate | Line # | Download | only in common
      1  1.102       ryo /*	$NetBSD: linux_exec_elf32.c,v 1.102 2021/11/26 09:05:05 ryo 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.102       ryo __KERNEL_RCSID(0, "$NetBSD: linux_exec_elf32.c,v 1.102 2021/11/26 09:05:05 ryo 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.56  christos #ifdef DEBUG_LINUX
     78   1.56  christos #define DPRINTF(a)	uprintf a
     79   1.56  christos #else
     80   1.96   msaitoh #define DPRINTF(a)	do {} while (0)
     81   1.56  christos #endif
     82   1.56  christos 
     83   1.51      manu #ifdef LINUX_ATEXIT_SIGNATURE
     84   1.51      manu /*
     85   1.51      manu  * On the PowerPC, statically linked Linux binaries are not recognized
     86   1.51      manu  * by linux_signature nor by linux_gcc_signature. Fortunately, thoses
     87   1.51      manu  * binaries features a __libc_atexit ELF section. We therefore assume we
     88   1.51      manu  * have a Linux binary if we find this section.
     89   1.51      manu  */
     90   1.71      manu int
     91   1.86      matt ELFNAME2(linux,atexit_signature)(
     92   1.86      matt 	struct lwp *l,
     93   1.86      matt 	struct exec_package *epp,
     94   1.86      matt 	Elf_Ehdr *eh)
     95   1.51      manu {
     96   1.91      maxv 	Elf_Shdr *sh;
     97   1.51      manu 	size_t shsize;
     98   1.91      maxv 	u_int shstrndx;
     99   1.51      manu 	size_t i;
    100   1.51      manu 	static const char signature[] = "__libc_atexit";
    101   1.91      maxv 	const size_t sigsz = sizeof(signature);
    102   1.91      maxv 	char tbuf[sizeof(signature)];
    103   1.51      manu 	int error;
    104   1.51      manu 
    105   1.91      maxv 	/* Load the section header table. */
    106   1.51      manu 	shsize = eh->e_shnum * sizeof(Elf_Shdr);
    107   1.51      manu 	sh = (Elf_Shdr *) malloc(shsize, M_TEMP, M_WAITOK);
    108  1.100        ad 	error = exec_read(l, epp->ep_vp, eh->e_shoff, sh, shsize,
    109  1.100        ad 	    IO_NODELOCKED);
    110   1.51      manu 	if (error)
    111   1.51      manu 		goto out;
    112   1.51      manu 
    113   1.91      maxv 	/* Now let's find the string table. If it does not exist, give up. */
    114   1.91      maxv 	shstrndx = eh->e_shstrndx;
    115   1.91      maxv 	if (shstrndx == SHN_UNDEF || shstrndx >= eh->e_shnum) {
    116   1.51      manu 		error = ENOEXEC;
    117   1.51      manu 		goto out;
    118   1.51      manu 	}
    119   1.51      manu 
    120   1.91      maxv 	/* Check if any section has the name we're looking for. */
    121   1.91      maxv 	const off_t stroff = sh[shstrndx].sh_offset;
    122   1.51      manu 	for (i = 0; i < eh->e_shnum; i++) {
    123   1.51      manu 		Elf_Shdr *s = &sh[i];
    124   1.91      maxv 
    125   1.91      maxv 		if (s->sh_name + sigsz > sh[shstrndx].sh_size)
    126   1.91      maxv 			continue;
    127   1.91      maxv 
    128  1.100        ad 		error = exec_read(l, epp->ep_vp, stroff + s->sh_name, tbuf,
    129  1.100        ad 		    sigsz, IO_NODELOCKED);
    130   1.91      maxv 		if (error)
    131   1.91      maxv 			goto out;
    132   1.91      maxv 		if (!memcmp(tbuf, signature, sigsz)) {
    133   1.91      maxv 			DPRINTF(("linux_atexit_sig=%s\n", tbuf));
    134   1.51      manu 			error = 0;
    135   1.51      manu 			goto out;
    136   1.51      manu 		}
    137   1.51      manu 	}
    138   1.51      manu 	error = ENOEXEC;
    139   1.51      manu 
    140   1.51      manu out:
    141   1.51      manu 	free(sh, M_TEMP);
    142   1.51      manu 	return (error);
    143   1.51      manu }
    144   1.51      manu #endif
    145    1.4  christos 
    146   1.31       erh #ifdef LINUX_GCC_SIGNATURE
    147   1.14  christos /*
    148   1.14  christos  * Take advantage of the fact that all the linux binaries are compiled
    149   1.14  christos  * with gcc, and gcc sticks in the comment field a signature. Note that
    150   1.14  christos  * on SVR4 binaries, the gcc signature will follow the OS name signature,
    151   1.14  christos  * that will not be a problem. We don't bother to read in the string table,
    152   1.14  christos  * but we check all the progbits headers.
    153   1.31       erh  *
    154   1.31       erh  * XXX This only works in the i386.  On the alpha (at least)
    155   1.31       erh  * XXX we have the same gcc signature which incorrectly identifies
    156   1.31       erh  * XXX NetBSD binaries as Linux.
    157   1.14  christos  */
    158   1.71      manu int
    159   1.86      matt ELFNAME2(linux,gcc_signature)(
    160   1.86      matt 	struct lwp *l,
    161   1.86      matt 	struct exec_package *epp,
    162   1.86      matt 	Elf_Ehdr *eh)
    163   1.14  christos {
    164   1.50   mycroft 	size_t shsize;
    165   1.14  christos 	size_t i;
    166   1.14  christos 	static const char signature[] = "\0GCC: (GNU) ";
    167   1.69  christos 	char tbuf[sizeof(signature) - 1];
    168   1.31       erh 	Elf_Shdr *sh;
    169   1.14  christos 	int error;
    170   1.14  christos 
    171   1.50   mycroft 	shsize = eh->e_shnum * sizeof(Elf_Shdr);
    172   1.31       erh 	sh = (Elf_Shdr *) malloc(shsize, M_TEMP, M_WAITOK);
    173  1.100        ad 	error = exec_read(l, epp->ep_vp, eh->e_shoff, sh, shsize,
    174  1.100        ad 	    IO_NODELOCKED);
    175   1.50   mycroft 	if (error)
    176   1.14  christos 		goto out;
    177   1.14  christos 
    178   1.14  christos 	for (i = 0; i < eh->e_shnum; i++) {
    179   1.31       erh 		Elf_Shdr *s = &sh[i];
    180   1.14  christos 
    181   1.14  christos 		/*
    182   1.14  christos 		 * Identify candidates for the comment header;
    183   1.15  christos 		 * Header cannot have a load address, or flags and
    184   1.14  christos 		 * it must be large enough.
    185   1.14  christos 		 */
    186   1.43    kleink 		if (s->sh_type != SHT_PROGBITS ||
    187   1.14  christos 		    s->sh_addr != 0 ||
    188   1.14  christos 		    s->sh_flags != 0 ||
    189   1.14  christos 		    s->sh_size < sizeof(signature) - 1)
    190   1.14  christos 			continue;
    191   1.14  christos 
    192  1.100        ad 		error = exec_read(l, epp->ep_vp, s->sh_offset, tbuf,
    193  1.100        ad 		    sizeof(signature) - 1, IO_NODELOCKED);
    194   1.50   mycroft 		if (error)
    195   1.50   mycroft 			continue;
    196   1.14  christos 
    197   1.15  christos 		/*
    198   1.15  christos 		 * error is 0, if the signatures match we are done.
    199   1.15  christos 		 */
    200   1.69  christos 		DPRINTF(("linux_gcc_sig: sig=%s\n", tbuf));
    201   1.69  christos 		if (!memcmp(tbuf, signature, sizeof(signature) - 1)) {
    202   1.50   mycroft 			error = 0;
    203   1.14  christos 			goto out;
    204   1.50   mycroft 		}
    205   1.14  christos 	}
    206   1.50   mycroft 	error = ENOEXEC;
    207   1.14  christos 
    208   1.14  christos out:
    209   1.14  christos 	free(sh, M_TEMP);
    210   1.50   mycroft 	return (error);
    211   1.14  christos }
    212   1.31       erh #endif
    213   1.31       erh 
    214   1.74      manu #ifdef LINUX_DEBUGLINK_SIGNATURE
    215   1.74      manu /*
    216   1.91      maxv  * Look for a .gnu_debuglink, specific to x86_64 interpreter
    217   1.74      manu  */
    218   1.74      manu int
    219   1.83    cegger ELFNAME2(linux,debuglink_signature)(struct lwp *l, struct exec_package *epp, Elf_Ehdr *eh)
    220   1.74      manu {
    221   1.91      maxv 	Elf_Shdr *sh;
    222   1.74      manu 	size_t shsize;
    223   1.91      maxv 	u_int shstrndx;
    224   1.74      manu 	size_t i;
    225   1.74      manu 	static const char signature[] = ".gnu_debuglink";
    226   1.91      maxv 	const size_t sigsz = sizeof(signature);
    227   1.91      maxv 	char tbuf[sizeof(signature)];
    228   1.74      manu 	int error;
    229   1.74      manu 
    230   1.91      maxv 	/* Load the section header table. */
    231   1.74      manu 	shsize = eh->e_shnum * sizeof(Elf_Shdr);
    232   1.74      manu 	sh = (Elf_Shdr *) malloc(shsize, M_TEMP, M_WAITOK);
    233  1.100        ad 	error = exec_read(l, epp->ep_vp, eh->e_shoff, sh, shsize,
    234  1.100        ad 	    IO_NODELOCKED);
    235   1.74      manu 	if (error)
    236   1.74      manu 		goto out;
    237   1.74      manu 
    238   1.91      maxv 	/* Now let's find the string table. If it does not exist, give up. */
    239   1.91      maxv 	shstrndx = eh->e_shstrndx;
    240   1.91      maxv 	if (shstrndx == SHN_UNDEF || shstrndx >= eh->e_shnum) {
    241   1.74      manu 		error = ENOEXEC;
    242   1.74      manu 		goto out;
    243   1.74      manu 	}
    244   1.74      manu 
    245   1.91      maxv 	/* Check if any section has the name we're looking for. */
    246   1.91      maxv 	const off_t stroff = sh[shstrndx].sh_offset;
    247   1.74      manu 	for (i = 0; i < eh->e_shnum; i++) {
    248   1.74      manu 		Elf_Shdr *s = &sh[i];
    249   1.74      manu 
    250   1.91      maxv 		if (s->sh_name + sigsz > sh[shstrndx].sh_size)
    251   1.91      maxv 			continue;
    252   1.91      maxv 
    253  1.100        ad 		error = exec_read(l, epp->ep_vp, stroff + s->sh_name, tbuf,
    254  1.100        ad 		    sigsz, IO_NODELOCKED);
    255   1.91      maxv 		if (error)
    256   1.91      maxv 			goto out;
    257   1.91      maxv 		if (!memcmp(tbuf, signature, sigsz)) {
    258   1.91      maxv 			DPRINTF(("linux_debuglink_sig=%s\n", tbuf));
    259   1.74      manu 			error = 0;
    260   1.74      manu 			goto out;
    261   1.74      manu 		}
    262   1.74      manu 	}
    263   1.74      manu 	error = ENOEXEC;
    264   1.74      manu 
    265   1.74      manu out:
    266   1.74      manu 	free(sh, M_TEMP);
    267   1.74      manu 	return (error);
    268   1.74      manu }
    269   1.74      manu #endif
    270   1.74      manu 
    271   1.95  christos #ifdef LINUX_GO_RT0_SIGNATURE
    272   1.95  christos /*
    273   1.95  christos  * Look for a .gopclntab, specific to go binaries
    274   1.95  christos  * in it look for a symbol called _rt0_<cpu>_linux
    275   1.95  christos  */
    276  1.101       ryo int
    277   1.95  christos ELFNAME2(linux,go_rt0_signature)(struct lwp *l, struct exec_package *epp, Elf_Ehdr *eh)
    278   1.95  christos {
    279   1.95  christos 	Elf_Shdr *sh;
    280   1.95  christos 	size_t shsize;
    281   1.95  christos 	u_int shstrndx;
    282   1.95  christos 	size_t i;
    283   1.95  christos 	static const char signature[] = ".gopclntab";
    284   1.95  christos 	const size_t sigsz = sizeof(signature);
    285   1.95  christos 	char tbuf[sizeof(signature)], *tmp = NULL;
    286   1.95  christos 	char mbuf[64];
    287   1.95  christos 	const char *m;
    288   1.95  christos 	int mlen;
    289   1.95  christos 	int error;
    290   1.95  christos 
    291   1.95  christos 	/* Load the section header table. */
    292   1.95  christos 	shsize = eh->e_shnum * sizeof(Elf_Shdr);
    293   1.95  christos 	sh = malloc(shsize, M_TEMP, M_WAITOK);
    294  1.100        ad 	error = exec_read(l, epp->ep_vp, eh->e_shoff, sh, shsize,
    295  1.100        ad 	    IO_NODELOCKED);
    296   1.95  christos 	if (error)
    297   1.95  christos 		goto out;
    298   1.95  christos 
    299   1.95  christos 	/* Now let's find the string table. If it does not exist, give up. */
    300   1.95  christos 	shstrndx = eh->e_shstrndx;
    301   1.95  christos 	if (shstrndx == SHN_UNDEF || shstrndx >= eh->e_shnum) {
    302   1.95  christos 		error = ENOEXEC;
    303   1.95  christos 		goto out;
    304   1.95  christos 	}
    305   1.95  christos 
    306   1.95  christos 	/* Check if any section has the name we're looking for. */
    307   1.95  christos 	const off_t stroff = sh[shstrndx].sh_offset;
    308   1.95  christos 	for (i = 0; i < eh->e_shnum; i++) {
    309   1.95  christos 		Elf_Shdr *s = &sh[i];
    310   1.95  christos 
    311   1.95  christos 		if (s->sh_name + sigsz > sh[shstrndx].sh_size)
    312   1.95  christos 			continue;
    313   1.95  christos 
    314  1.100        ad 		error = exec_read(l, epp->ep_vp, stroff + s->sh_name, tbuf,
    315  1.100        ad 		    sigsz, IO_NODELOCKED);
    316   1.95  christos 		if (error)
    317   1.95  christos 			goto out;
    318   1.95  christos 		if (!memcmp(tbuf, signature, sigsz)) {
    319   1.96   msaitoh 			DPRINTF(("linux_goplcntab_sig=%s\n", tbuf));
    320   1.95  christos 			break;
    321   1.95  christos 		}
    322   1.95  christos 	}
    323   1.95  christos 
    324   1.95  christos 	if (i == eh->e_shnum) {
    325   1.95  christos 		error = ENOEXEC;
    326   1.95  christos 		goto out;
    327   1.95  christos 	}
    328   1.95  christos 
    329   1.97  christos 	// Don't scan more than 1MB
    330   1.97  christos 	if (sh[i].sh_size > 1024 * 1024)
    331   1.97  christos 		sh[i].sh_size = 1024 * 1024;
    332   1.95  christos 
    333   1.95  christos 	tmp = malloc(sh[i].sh_size, M_TEMP, M_WAITOK);
    334  1.100        ad 	error = exec_read(l, epp->ep_vp, sh[i].sh_offset, tmp,
    335  1.100        ad 	    sh[i].sh_size, IO_NODELOCKED);
    336   1.95  christos 	if (error)
    337   1.95  christos 		goto out;
    338   1.95  christos 
    339   1.95  christos #if (ELFSIZE == 32)
    340  1.102       ryo #ifdef LINUX_GO_RT0_SIGNATURE_ARCH32
    341  1.102       ryo 	m = LINUX_GO_RT0_SIGNATURE_ARCH32;
    342  1.102       ryo #else
    343   1.98  pgoyette 	extern struct netbsd32_machine32_hook_t netbsd32_machine32_hook;
    344   1.99  pgoyette 	MODULE_HOOK_CALL(netbsd32_machine32_hook, (), machine, m);
    345  1.102       ryo #endif
    346  1.102       ryo #else /* (ELFSIZE == 32) */
    347  1.102       ryo #ifdef LINUX_GO_RT0_SIGNATURE_ARCH64
    348  1.102       ryo 	m = LINUX_GO_RT0_SIGNATURE_ARCH64;
    349   1.95  christos #else
    350   1.95  christos 	m = machine;
    351   1.95  christos #endif
    352  1.102       ryo #endif /* (ELFSIZE == 32) */
    353   1.95  christos 	mlen = snprintf(mbuf, sizeof(mbuf), "_rt0_%s_linux", m);
    354   1.95  christos 	if (memmem(tmp, sh[i].sh_size, mbuf, mlen) == NULL)
    355   1.95  christos 		error = ENOEXEC;
    356   1.95  christos 	else
    357   1.95  christos 		DPRINTF(("linux_rt0_sig=%s\n", mbuf));
    358   1.95  christos out:
    359   1.95  christos 	if (tmp)
    360   1.95  christos 		free(tmp, M_TEMP);
    361   1.95  christos 	free(sh, M_TEMP);
    362   1.95  christos 	return error;
    363   1.95  christos }
    364   1.95  christos #endif
    365   1.95  christos 
    366   1.71      manu int
    367   1.83    cegger ELFNAME2(linux,signature)(struct lwp *l, struct exec_package *epp, Elf_Ehdr *eh, char *itp)
    368   1.31       erh {
    369   1.31       erh 	size_t i;
    370   1.31       erh 	Elf_Phdr *ph;
    371   1.31       erh 	size_t phsize;
    372   1.50   mycroft 	int error;
    373   1.57  christos 	static const char linux[] = "Linux";
    374   1.57  christos 
    375   1.94       uwe 	if (eh->e_ident[EI_OSABI] == ELFOSABI_LINUX ||
    376   1.57  christos 	    memcmp(&eh->e_ident[EI_ABIVERSION], linux, sizeof(linux)) == 0)
    377   1.57  christos 		return 0;
    378   1.31       erh 
    379   1.31       erh 	phsize = eh->e_phnum * sizeof(Elf_Phdr);
    380   1.31       erh 	ph = (Elf_Phdr *)malloc(phsize, M_TEMP, M_WAITOK);
    381  1.100        ad 	error = exec_read(l, epp->ep_vp, eh->e_phoff, ph, phsize,
    382  1.100        ad 	    IO_NODELOCKED);
    383   1.50   mycroft 	if (error)
    384   1.50   mycroft 		goto out;
    385   1.31       erh 
    386   1.31       erh 	for (i = 0; i < eh->e_phnum; i++) {
    387   1.31       erh 		Elf_Phdr *ephp = &ph[i];
    388   1.50   mycroft 		Elf_Nhdr *np;
    389   1.50   mycroft 		u_int32_t *abi;
    390   1.31       erh 
    391   1.50   mycroft 		if (ephp->p_type != PT_NOTE ||
    392   1.50   mycroft 		    ephp->p_filesz > 1024 ||
    393   1.50   mycroft 		    ephp->p_filesz < sizeof(Elf_Nhdr) + 20)
    394   1.31       erh 			continue;
    395   1.31       erh 
    396   1.50   mycroft 		np = (Elf_Nhdr *)malloc(ephp->p_filesz, M_TEMP, M_WAITOK);
    397  1.100        ad 		error = exec_read(l, epp->ep_vp, ephp->p_offset, np,
    398  1.100        ad 		    ephp->p_filesz, IO_NODELOCKED);
    399   1.50   mycroft 		if (error)
    400   1.50   mycroft 			goto next;
    401   1.50   mycroft 
    402   1.50   mycroft 		if (np->n_type != ELF_NOTE_TYPE_ABI_TAG ||
    403   1.50   mycroft 		    np->n_namesz != ELF_NOTE_ABI_NAMESZ ||
    404   1.50   mycroft 		    np->n_descsz != ELF_NOTE_ABI_DESCSZ ||
    405   1.78  christos 		    memcmp((void *)(np + 1), ELF_NOTE_ABI_NAME,
    406   1.50   mycroft 		    ELF_NOTE_ABI_NAMESZ))
    407   1.50   mycroft 			goto next;
    408   1.50   mycroft 
    409   1.50   mycroft 		/* Make sure the OS is Linux. */
    410   1.78  christos 		abi = (u_int32_t *)((char *)np + sizeof(Elf_Nhdr) +
    411   1.50   mycroft 		    np->n_namesz);
    412   1.50   mycroft 		if (abi[0] == ELF_NOTE_ABI_OS_LINUX)
    413   1.50   mycroft 			error = 0;
    414   1.50   mycroft 		else
    415   1.40       erh 			error = ENOEXEC;
    416   1.50   mycroft 		free(np, M_TEMP);
    417   1.50   mycroft 		goto out;
    418   1.31       erh 
    419   1.50   mycroft 	next:
    420   1.50   mycroft 		free(np, M_TEMP);
    421   1.50   mycroft 		continue;
    422   1.50   mycroft 	}
    423   1.31       erh 
    424   1.91      maxv 	/* Check for certain interpreter names. */
    425   1.66  drochner 	if (itp) {
    426   1.50   mycroft 		if (!strncmp(itp, "/lib/ld-linux", 13) ||
    427   1.68      manu #if (ELFSIZE == 64)
    428   1.68      manu 		    !strncmp(itp, "/lib64/ld-linux", 15) ||
    429   1.68      manu #endif
    430   1.50   mycroft 		    !strncmp(itp, "/lib/ld.so.", 11))
    431   1.50   mycroft 			error = 0;
    432   1.50   mycroft 		else
    433   1.50   mycroft 			error = ENOEXEC;
    434   1.50   mycroft 		goto out;
    435   1.31       erh 	}
    436   1.31       erh 
    437   1.31       erh 	error = ENOEXEC;
    438   1.50   mycroft out:
    439   1.31       erh 	free(ph, M_TEMP);
    440   1.50   mycroft 	return (error);
    441   1.31       erh }
    442   1.14  christos 
    443    1.8      fvdl int
    444   1.75  christos ELFNAME2(linux,probe)(struct lwp *l, struct exec_package *epp, void *eh,
    445   1.76  christos     char *itp, vaddr_t *pos)
    446    1.6      fvdl {
    447    1.8      fvdl 	int error;
    448   1.14  christos 
    449   1.70  christos 	if (((error = ELFNAME2(linux,signature)(l, epp, eh, itp)) != 0) &&
    450   1.51      manu #ifdef LINUX_GCC_SIGNATURE
    451   1.70  christos 	    ((error = ELFNAME2(linux,gcc_signature)(l, epp, eh)) != 0) &&
    452   1.53      manu #endif
    453   1.51      manu #ifdef LINUX_ATEXIT_SIGNATURE
    454   1.70  christos 	    ((error = ELFNAME2(linux,atexit_signature)(l, epp, eh)) != 0) &&
    455   1.53      manu #endif
    456   1.74      manu #ifdef LINUX_DEBUGLINK_SIGNATURE
    457   1.74      manu 	    ((error = ELFNAME2(linux,debuglink_signature)(l, epp, eh)) != 0) &&
    458   1.74      manu #endif
    459   1.95  christos #ifdef LINUX_GO_RT0_SIGNATURE
    460   1.95  christos 	    ((error = ELFNAME2(linux,go_rt0_signature)(l, epp, eh)) != 0) &&
    461   1.95  christos #endif
    462   1.74      manu 	    1) {
    463   1.74      manu 			DPRINTF(("linux_probe: returning %d\n", error));
    464   1.51      manu 			return error;
    465   1.74      manu 	}
    466    1.6      fvdl 
    467   1.66  drochner 	if (itp) {
    468   1.79       dsl 		if ((error = emul_find_interp(l, epp, itp)))
    469   1.60  jdolecek 			return (error);
    470    1.6      fvdl 	}
    471   1.84       chs 	epp->ep_flags |= EXEC_FORCEAUX;
    472   1.56  christos 	DPRINTF(("linux_probe: returning 0\n"));
    473    1.6      fvdl 	return 0;
    474    1.6      fvdl }
    475    1.6      fvdl 
    476   1.59  jdolecek #ifndef LINUX_MACHDEP_ELF_COPYARGS
    477   1.59  jdolecek /*
    478   1.59  jdolecek  * Copy arguments onto the stack in the normal way, but add some
    479   1.59  jdolecek  * extra information in case of dynamic binding.
    480   1.59  jdolecek  */
    481   1.59  jdolecek int
    482   1.70  christos ELFNAME2(linux,copyargs)(struct lwp *l, struct exec_package *pack,
    483   1.59  jdolecek     struct ps_strings *arginfo, char **stackp, void *argp)
    484   1.59  jdolecek {
    485   1.59  jdolecek 	size_t len;
    486   1.59  jdolecek 	AuxInfo ai[LINUX_ELF_AUX_ENTRIES], *a;
    487   1.59  jdolecek 	struct elf_args *ap;
    488   1.59  jdolecek 	int error;
    489   1.59  jdolecek 	struct vattr *vap;
    490   1.87       chs 	uint32_t randbytes[4];
    491   1.59  jdolecek 
    492   1.70  christos 	if ((error = copyargs(l, pack, arginfo, stackp, argp)) != 0)
    493   1.59  jdolecek 		return error;
    494   1.59  jdolecek 
    495   1.59  jdolecek 	a = ai;
    496   1.59  jdolecek 
    497   1.92      maxv 	memset(ai, 0, sizeof(ai));
    498   1.92      maxv 
    499   1.59  jdolecek 	/*
    500   1.59  jdolecek 	 * Push extra arguments used by glibc on the stack.
    501   1.59  jdolecek 	 */
    502   1.59  jdolecek 
    503   1.59  jdolecek 	a->a_type = AT_PAGESZ;
    504   1.59  jdolecek 	a->a_v = PAGE_SIZE;
    505   1.59  jdolecek 	a++;
    506   1.59  jdolecek 
    507   1.59  jdolecek 	if ((ap = (struct elf_args *)pack->ep_emul_arg)) {
    508   1.59  jdolecek 
    509   1.59  jdolecek 		a->a_type = AT_PHDR;
    510   1.59  jdolecek 		a->a_v = ap->arg_phaddr;
    511   1.59  jdolecek 		a++;
    512   1.59  jdolecek 
    513   1.59  jdolecek 		a->a_type = AT_PHENT;
    514   1.59  jdolecek 		a->a_v = ap->arg_phentsize;
    515   1.59  jdolecek 		a++;
    516   1.59  jdolecek 
    517   1.59  jdolecek 		a->a_type = AT_PHNUM;
    518   1.59  jdolecek 		a->a_v = ap->arg_phnum;
    519   1.59  jdolecek 		a++;
    520   1.59  jdolecek 
    521   1.59  jdolecek 		a->a_type = AT_BASE;
    522   1.59  jdolecek 		a->a_v = ap->arg_interp;
    523   1.59  jdolecek 		a++;
    524   1.59  jdolecek 
    525   1.59  jdolecek 		a->a_type = AT_FLAGS;
    526   1.59  jdolecek 		a->a_v = 0;
    527   1.59  jdolecek 		a++;
    528   1.59  jdolecek 
    529   1.59  jdolecek 		a->a_type = AT_ENTRY;
    530   1.59  jdolecek 		a->a_v = ap->arg_entry;
    531   1.59  jdolecek 		a++;
    532   1.59  jdolecek 
    533   1.85      matt 		exec_free_emul_arg(pack);
    534   1.59  jdolecek 	}
    535   1.59  jdolecek 
    536   1.59  jdolecek 	/* Linux-specific items */
    537   1.59  jdolecek 	a->a_type = LINUX_AT_CLKTCK;
    538   1.59  jdolecek 	a->a_v = hz;
    539   1.59  jdolecek 	a++;
    540   1.59  jdolecek 
    541   1.59  jdolecek 	vap = pack->ep_vap;
    542   1.59  jdolecek 
    543   1.59  jdolecek 	a->a_type = LINUX_AT_UID;
    544   1.73        ad 	a->a_v = kauth_cred_getuid(l->l_cred);
    545   1.59  jdolecek 	a++;
    546   1.59  jdolecek 
    547   1.59  jdolecek 	a->a_type = LINUX_AT_EUID;
    548   1.59  jdolecek 	if (vap->va_mode & S_ISUID)
    549   1.59  jdolecek 		a->a_v = vap->va_uid;
    550   1.59  jdolecek 	else
    551   1.73        ad 		a->a_v = kauth_cred_geteuid(l->l_cred);
    552   1.59  jdolecek 	a++;
    553   1.59  jdolecek 
    554   1.59  jdolecek 	a->a_type = LINUX_AT_GID;
    555   1.73        ad 	a->a_v = kauth_cred_getgid(l->l_cred);
    556   1.59  jdolecek 	a++;
    557   1.59  jdolecek 
    558   1.59  jdolecek 	a->a_type = LINUX_AT_EGID;
    559   1.59  jdolecek 	if (vap->va_mode & S_ISGID)
    560   1.59  jdolecek 		a->a_v = vap->va_gid;
    561   1.59  jdolecek 	else
    562   1.73        ad 		a->a_v = kauth_cred_getegid(l->l_cred);
    563   1.59  jdolecek 	a++;
    564   1.59  jdolecek 
    565   1.87       chs 	a->a_type = LINUX_AT_RANDOM;
    566   1.93      matt 	a->a_v = (Elf_Addr)(uintptr_t)*stackp;
    567   1.87       chs 	a++;
    568   1.87       chs 
    569   1.59  jdolecek 	a->a_type = AT_NULL;
    570   1.59  jdolecek 	a->a_v = 0;
    571   1.59  jdolecek 	a++;
    572   1.59  jdolecek 
    573   1.88       chs 	randbytes[0] = cprng_strong32();
    574   1.88       chs 	randbytes[1] = cprng_strong32();
    575   1.88       chs 	randbytes[2] = cprng_strong32();
    576   1.88       chs 	randbytes[3] = cprng_strong32();
    577   1.87       chs 
    578   1.87       chs 	len = sizeof(randbytes);
    579   1.87       chs 	if ((error = copyout(randbytes, *stackp, len)) != 0)
    580   1.87       chs 		return error;
    581   1.87       chs 	*stackp += len;
    582   1.87       chs 
    583   1.59  jdolecek 	len = (a - ai) * sizeof(AuxInfo);
    584   1.90     njoly 	KASSERT(len <= LINUX_ELF_AUX_ENTRIES * sizeof(AuxInfo));
    585   1.59  jdolecek 	if ((error = copyout(ai, *stackp, len)) != 0)
    586   1.59  jdolecek 		return error;
    587   1.59  jdolecek 	*stackp += len;
    588   1.59  jdolecek 
    589   1.59  jdolecek 	return 0;
    590   1.59  jdolecek }
    591   1.59  jdolecek #endif /* !LINUX_MACHDEP_ELF_COPYARGS */
    592