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