Home | History | Annotate | Line # | Download | only in common
linux_exec_elf32.c revision 1.71
      1 /*	$NetBSD: linux_exec_elf32.c,v 1.71 2006/02/09 19:18:56 manu Exp $	*/
      2 
      3 /*-
      4  * Copyright (c) 1995, 1998, 2000, 2001 The NetBSD Foundation, Inc.
      5  * All rights reserved.
      6  *
      7  * This code is derived from software contributed to The NetBSD Foundation
      8  * by Christos Zoulas, Frank van der Linden, Eric Haszlakiewicz and
      9  * Emmanuel Dreyfus.
     10  *
     11  * Redistribution and use in source and binary forms, with or without
     12  * modification, are permitted provided that the following conditions
     13  * are met:
     14  * 1. Redistributions of source code must retain the above copyright
     15  *    notice, this list of conditions and the following disclaimer.
     16  * 2. Redistributions in binary form must reproduce the above copyright
     17  *    notice, this list of conditions and the following disclaimer in the
     18  *    documentation and/or other materials provided with the distribution.
     19  * 3. All advertising materials mentioning features or use of this software
     20  *    must display the following acknowledgement:
     21  *	This product includes software developed by the NetBSD
     22  *	Foundation, Inc. and its contributors.
     23  * 4. Neither the name of The NetBSD Foundation nor the names of its
     24  *    contributors may be used to endorse or promote products derived
     25  *    from this software without specific prior written permission.
     26  *
     27  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     28  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     29  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     30  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     31  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     32  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     33  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     34  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     35  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     36  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     37  * POSSIBILITY OF SUCH DAMAGE.
     38  */
     39 
     40 /*
     41  * based on exec_aout.c, sunos_exec.c and svr4_exec.c
     42  */
     43 
     44 #include <sys/cdefs.h>
     45 __KERNEL_RCSID(0, "$NetBSD: linux_exec_elf32.c,v 1.71 2006/02/09 19:18:56 manu Exp $");
     46 
     47 #ifndef ELFSIZE
     48 /* XXX should die */
     49 #define	ELFSIZE		32
     50 #endif
     51 
     52 #include <sys/param.h>
     53 #include <sys/systm.h>
     54 #include <sys/kernel.h>
     55 #include <sys/proc.h>
     56 #include <sys/malloc.h>
     57 #include <sys/namei.h>
     58 #include <sys/vnode.h>
     59 #include <sys/mount.h>
     60 #include <sys/exec.h>
     61 #include <sys/exec_elf.h>
     62 #include <sys/stat.h>
     63 
     64 #include <sys/mman.h>
     65 #include <sys/sa.h>
     66 #include <sys/syscallargs.h>
     67 
     68 #include <machine/cpu.h>
     69 #include <machine/reg.h>
     70 
     71 #include <compat/linux/common/linux_types.h>
     72 #include <compat/linux/common/linux_signal.h>
     73 #include <compat/linux/common/linux_util.h>
     74 #include <compat/linux/common/linux_exec.h>
     75 #include <compat/linux/common/linux_machdep.h>
     76 
     77 #include <compat/linux/linux_syscallargs.h>
     78 #include <compat/linux/linux_syscall.h>
     79 
     80 #ifdef DEBUG_LINUX
     81 #define DPRINTF(a)	uprintf a
     82 #else
     83 #define DPRINTF(a)
     84 #endif
     85 
     86 #ifdef LINUX_ATEXIT_SIGNATURE
     87 /*
     88  * On the PowerPC, statically linked Linux binaries are not recognized
     89  * by linux_signature nor by linux_gcc_signature. Fortunately, thoses
     90  * binaries features a __libc_atexit ELF section. We therefore assume we
     91  * have a Linux binary if we find this section.
     92  */
     93 int
     94 ELFNAME2(linux,atexit_signature)(l, epp, eh)
     95 	struct lwp *l;
     96 	struct exec_package *epp;
     97 	Elf_Ehdr *eh;
     98 {
     99 	size_t shsize;
    100 	int strndx;
    101 	size_t i;
    102 	static const char signature[] = "__libc_atexit";
    103 	char *strtable = NULL;
    104 	Elf_Shdr *sh;
    105 
    106 	int error;
    107 
    108 	/*
    109 	 * load the section header table
    110 	 */
    111 	shsize = eh->e_shnum * sizeof(Elf_Shdr);
    112 	sh = (Elf_Shdr *) malloc(shsize, M_TEMP, M_WAITOK);
    113 	error = exec_read_from(l, epp->ep_vp, eh->e_shoff, sh, shsize);
    114 	if (error)
    115 		goto out;
    116 
    117 	/*
    118 	 * Now let's find the string table. If it does not exists, give up.
    119 	 */
    120 	strndx = (int)(eh->e_shstrndx);
    121 	if (strndx == SHN_UNDEF) {
    122 		error = ENOEXEC;
    123 		goto out;
    124 	}
    125 
    126 	/*
    127 	 * strndx is the index in section header table of the string table
    128 	 * section get the whole string table in strtable, and then we get access to the names
    129 	 * s->sh_name is the offset of the section name in strtable.
    130 	 */
    131 	strtable = malloc(sh[strndx].sh_size, M_TEMP, M_WAITOK);
    132 	error = exec_read_from(l, epp->ep_vp, sh[strndx].sh_offset, strtable,
    133 	    sh[strndx].sh_size);
    134 	if (error)
    135 		goto out;
    136 
    137 	for (i = 0; i < eh->e_shnum; i++) {
    138 		Elf_Shdr *s = &sh[i];
    139 		if (!memcmp((void*)(&(strtable[s->sh_name])), signature,
    140 				sizeof(signature))) {
    141 			DPRINTF(("linux_atexit_sig=%s\n",
    142 			    &(strtable[s->sh_name])));
    143 			error = 0;
    144 			goto out;
    145 		}
    146 	}
    147 	error = ENOEXEC;
    148 
    149 out:
    150 	free(sh, M_TEMP);
    151 	if (strtable)
    152 		free(strtable, M_TEMP);
    153 	return (error);
    154 }
    155 #endif
    156 
    157 #ifdef LINUX_GCC_SIGNATURE
    158 /*
    159  * Take advantage of the fact that all the linux binaries are compiled
    160  * with gcc, and gcc sticks in the comment field a signature. Note that
    161  * on SVR4 binaries, the gcc signature will follow the OS name signature,
    162  * that will not be a problem. We don't bother to read in the string table,
    163  * but we check all the progbits headers.
    164  *
    165  * XXX This only works in the i386.  On the alpha (at least)
    166  * XXX we have the same gcc signature which incorrectly identifies
    167  * XXX NetBSD binaries as Linux.
    168  */
    169 int
    170 ELFNAME2(linux,gcc_signature)(l, epp, eh)
    171 	struct lwp *l;
    172 	struct exec_package *epp;
    173 	Elf_Ehdr *eh;
    174 {
    175 	size_t shsize;
    176 	size_t i;
    177 	static const char signature[] = "\0GCC: (GNU) ";
    178 	char tbuf[sizeof(signature) - 1];
    179 	Elf_Shdr *sh;
    180 	int error;
    181 
    182 	shsize = eh->e_shnum * sizeof(Elf_Shdr);
    183 	sh = (Elf_Shdr *) malloc(shsize, M_TEMP, M_WAITOK);
    184 	error = exec_read_from(l, epp->ep_vp, eh->e_shoff, sh, shsize);
    185 	if (error)
    186 		goto out;
    187 
    188 	for (i = 0; i < eh->e_shnum; i++) {
    189 		Elf_Shdr *s = &sh[i];
    190 
    191 		/*
    192 		 * Identify candidates for the comment header;
    193 		 * Header cannot have a load address, or flags and
    194 		 * it must be large enough.
    195 		 */
    196 		if (s->sh_type != SHT_PROGBITS ||
    197 		    s->sh_addr != 0 ||
    198 		    s->sh_flags != 0 ||
    199 		    s->sh_size < sizeof(signature) - 1)
    200 			continue;
    201 
    202 		error = exec_read_from(l, epp->ep_vp, s->sh_offset, tbuf,
    203 		    sizeof(signature) - 1);
    204 		if (error)
    205 			continue;
    206 
    207 		/*
    208 		 * error is 0, if the signatures match we are done.
    209 		 */
    210 		DPRINTF(("linux_gcc_sig: sig=%s\n", tbuf));
    211 		if (!memcmp(tbuf, signature, sizeof(signature) - 1)) {
    212 			error = 0;
    213 			goto out;
    214 		}
    215 	}
    216 	error = ENOEXEC;
    217 
    218 out:
    219 	free(sh, M_TEMP);
    220 	return (error);
    221 }
    222 #endif
    223 
    224 int
    225 ELFNAME2(linux,signature)(l, epp, eh, itp)
    226 	struct lwp *l;
    227 	struct exec_package *epp;
    228 	Elf_Ehdr *eh;
    229 	char *itp;
    230 {
    231 	size_t i;
    232 	Elf_Phdr *ph;
    233 	size_t phsize;
    234 	int error;
    235 	static const char linux[] = "Linux";
    236 
    237 	if (eh->e_ident[EI_OSABI] == 3 ||
    238 	    memcmp(&eh->e_ident[EI_ABIVERSION], linux, sizeof(linux)) == 0)
    239 		return 0;
    240 
    241 	phsize = eh->e_phnum * sizeof(Elf_Phdr);
    242 	ph = (Elf_Phdr *)malloc(phsize, M_TEMP, M_WAITOK);
    243 	error = exec_read_from(l, epp->ep_vp, eh->e_phoff, ph, phsize);
    244 	if (error)
    245 		goto out;
    246 
    247 	for (i = 0; i < eh->e_phnum; i++) {
    248 		Elf_Phdr *ephp = &ph[i];
    249 		Elf_Nhdr *np;
    250 		u_int32_t *abi;
    251 
    252 		if (ephp->p_type != PT_NOTE ||
    253 		    ephp->p_filesz > 1024 ||
    254 		    ephp->p_filesz < sizeof(Elf_Nhdr) + 20)
    255 			continue;
    256 
    257 		np = (Elf_Nhdr *)malloc(ephp->p_filesz, M_TEMP, M_WAITOK);
    258 		error = exec_read_from(l, epp->ep_vp, ephp->p_offset, np,
    259 		    ephp->p_filesz);
    260 		if (error)
    261 			goto next;
    262 
    263 		if (np->n_type != ELF_NOTE_TYPE_ABI_TAG ||
    264 		    np->n_namesz != ELF_NOTE_ABI_NAMESZ ||
    265 		    np->n_descsz != ELF_NOTE_ABI_DESCSZ ||
    266 		    memcmp((caddr_t)(np + 1), ELF_NOTE_ABI_NAME,
    267 		    ELF_NOTE_ABI_NAMESZ))
    268 			goto next;
    269 
    270 		/* Make sure the OS is Linux. */
    271 		abi = (u_int32_t *)((caddr_t)np + sizeof(Elf_Nhdr) +
    272 		    np->n_namesz);
    273 		if (abi[0] == ELF_NOTE_ABI_OS_LINUX)
    274 			error = 0;
    275 		else
    276 			error = ENOEXEC;
    277 		free(np, M_TEMP);
    278 		goto out;
    279 
    280 	next:
    281 		free(np, M_TEMP);
    282 		continue;
    283 	}
    284 
    285 	/* Check for certain intepreter names. */
    286 	if (itp) {
    287 		if (!strncmp(itp, "/lib/ld-linux", 13) ||
    288 #if (ELFSIZE == 64)
    289 		    !strncmp(itp, "/lib64/ld-linux", 15) ||
    290 #endif
    291 		    !strncmp(itp, "/lib/ld.so.", 11))
    292 			error = 0;
    293 		else
    294 			error = ENOEXEC;
    295 		goto out;
    296 	}
    297 
    298 	error = ENOEXEC;
    299 out:
    300 	free(ph, M_TEMP);
    301 	return (error);
    302 }
    303 
    304 int
    305 ELFNAME2(linux,probe)(l, epp, eh, itp, pos)
    306 	struct lwp *l;
    307 	struct exec_package *epp;
    308 	void *eh;
    309 	char *itp;
    310 	vaddr_t *pos;
    311 {
    312 	int error;
    313 
    314 	if (((error = ELFNAME2(linux,signature)(l, epp, eh, itp)) != 0) &&
    315 #ifdef LINUX_GCC_SIGNATURE
    316 	    ((error = ELFNAME2(linux,gcc_signature)(l, epp, eh)) != 0) &&
    317 #endif
    318 #ifdef LINUX_ATEXIT_SIGNATURE
    319 	    ((error = ELFNAME2(linux,atexit_signature)(l, epp, eh)) != 0) &&
    320 #endif
    321 	    1)
    322 			return error;
    323 
    324 	if (itp) {
    325 		if ((error = emul_find_interp(l, epp->ep_esch->es_emul->e_path,
    326 		    itp)))
    327 			return (error);
    328 	}
    329 	DPRINTF(("linux_probe: returning 0\n"));
    330 	return 0;
    331 }
    332 
    333 #ifndef LINUX_MACHDEP_ELF_COPYARGS
    334 /*
    335  * Copy arguments onto the stack in the normal way, but add some
    336  * extra information in case of dynamic binding.
    337  */
    338 int
    339 ELFNAME2(linux,copyargs)(struct lwp *l, struct exec_package *pack,
    340     struct ps_strings *arginfo, char **stackp, void *argp)
    341 {
    342 	struct proc *p = l->l_proc;
    343 	size_t len;
    344 	AuxInfo ai[LINUX_ELF_AUX_ENTRIES], *a;
    345 	struct elf_args *ap;
    346 	int error;
    347 	struct vattr *vap;
    348 
    349 	if ((error = copyargs(l, pack, arginfo, stackp, argp)) != 0)
    350 		return error;
    351 
    352 	a = ai;
    353 
    354 	/*
    355 	 * Push extra arguments used by glibc on the stack.
    356 	 */
    357 
    358 	a->a_type = AT_PAGESZ;
    359 	a->a_v = PAGE_SIZE;
    360 	a++;
    361 
    362 	if ((ap = (struct elf_args *)pack->ep_emul_arg)) {
    363 
    364 		a->a_type = AT_PHDR;
    365 		a->a_v = ap->arg_phaddr;
    366 		a++;
    367 
    368 		a->a_type = AT_PHENT;
    369 		a->a_v = ap->arg_phentsize;
    370 		a++;
    371 
    372 		a->a_type = AT_PHNUM;
    373 		a->a_v = ap->arg_phnum;
    374 		a++;
    375 
    376 		a->a_type = AT_BASE;
    377 		a->a_v = ap->arg_interp;
    378 		a++;
    379 
    380 		a->a_type = AT_FLAGS;
    381 		a->a_v = 0;
    382 		a++;
    383 
    384 		a->a_type = AT_ENTRY;
    385 		a->a_v = ap->arg_entry;
    386 		a++;
    387 
    388 		free(pack->ep_emul_arg, M_TEMP);
    389 		pack->ep_emul_arg = NULL;
    390 	}
    391 
    392 	/* Linux-specific items */
    393 	a->a_type = LINUX_AT_CLKTCK;
    394 	a->a_v = hz;
    395 	a++;
    396 
    397 	vap = pack->ep_vap;
    398 
    399 	a->a_type = LINUX_AT_UID;
    400 	a->a_v = p->p_cred->p_ruid;
    401 	a++;
    402 
    403 	a->a_type = LINUX_AT_EUID;
    404 	if (vap->va_mode & S_ISUID)
    405 		a->a_v = vap->va_uid;
    406 	else
    407 		a->a_v = p->p_ucred->cr_uid;
    408 	a++;
    409 
    410 	a->a_type = LINUX_AT_GID;
    411 	a->a_v = p->p_cred->p_rgid;
    412 	a++;
    413 
    414 	a->a_type = LINUX_AT_EGID;
    415 	if (vap->va_mode & S_ISGID)
    416 		a->a_v = vap->va_gid;
    417 	else
    418 		a->a_v = p->p_ucred->cr_gid;
    419 	a++;
    420 
    421 	a->a_type = AT_NULL;
    422 	a->a_v = 0;
    423 	a++;
    424 
    425 	len = (a - ai) * sizeof(AuxInfo);
    426 	if ((error = copyout(ai, *stackp, len)) != 0)
    427 		return error;
    428 	*stackp += len;
    429 
    430 	return 0;
    431 }
    432 #endif /* !LINUX_MACHDEP_ELF_COPYARGS */
    433