1 /* $NetBSD: linux_exec_elf32.c,v 1.74 2006/08/07 14:19:57 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.74 2006/08/07 14:19:57 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 #include <sys/kauth.h> 64 65 #include <sys/mman.h> 66 #include <sys/sa.h> 67 #include <sys/syscallargs.h> 68 69 #include <machine/cpu.h> 70 #include <machine/reg.h> 71 72 #include <compat/linux/common/linux_types.h> 73 #include <compat/linux/common/linux_signal.h> 74 #include <compat/linux/common/linux_util.h> 75 #include <compat/linux/common/linux_exec.h> 76 #include <compat/linux/common/linux_machdep.h> 77 78 #include <compat/linux/linux_syscallargs.h> 79 #include <compat/linux/linux_syscall.h> 80 81 #ifdef DEBUG_LINUX 82 #define DPRINTF(a) uprintf a 83 #else 84 #define DPRINTF(a) 85 #endif 86 87 #ifdef LINUX_ATEXIT_SIGNATURE 88 /* 89 * On the PowerPC, statically linked Linux binaries are not recognized 90 * by linux_signature nor by linux_gcc_signature. Fortunately, thoses 91 * binaries features a __libc_atexit ELF section. We therefore assume we 92 * have a Linux binary if we find this section. 93 */ 94 int 95 ELFNAME2(linux,atexit_signature)(l, epp, eh) 96 struct lwp *l; 97 struct exec_package *epp; 98 Elf_Ehdr *eh; 99 { 100 size_t shsize; 101 int strndx; 102 size_t i; 103 static const char signature[] = "__libc_atexit"; 104 char *strtable = NULL; 105 Elf_Shdr *sh; 106 107 int error; 108 109 /* 110 * load the section header table 111 */ 112 shsize = eh->e_shnum * sizeof(Elf_Shdr); 113 sh = (Elf_Shdr *) malloc(shsize, M_TEMP, M_WAITOK); 114 error = exec_read_from(l, epp->ep_vp, eh->e_shoff, sh, shsize); 115 if (error) 116 goto out; 117 118 /* 119 * Now let's find the string table. If it does not exists, give up. 120 */ 121 strndx = (int)(eh->e_shstrndx); 122 if (strndx == SHN_UNDEF) { 123 error = ENOEXEC; 124 goto out; 125 } 126 127 /* 128 * strndx is the index in section header table of the string table 129 * section get the whole string table in strtable, and then we get access to the names 130 * s->sh_name is the offset of the section name in strtable. 131 */ 132 strtable = malloc(sh[strndx].sh_size, M_TEMP, M_WAITOK); 133 error = exec_read_from(l, epp->ep_vp, sh[strndx].sh_offset, strtable, 134 sh[strndx].sh_size); 135 if (error) 136 goto out; 137 138 for (i = 0; i < eh->e_shnum; i++) { 139 Elf_Shdr *s = &sh[i]; 140 if (!memcmp((void*)(&(strtable[s->sh_name])), signature, 141 sizeof(signature))) { 142 DPRINTF(("linux_atexit_sig=%s\n", 143 &(strtable[s->sh_name]))); 144 error = 0; 145 goto out; 146 } 147 } 148 error = ENOEXEC; 149 150 out: 151 free(sh, M_TEMP); 152 if (strtable) 153 free(strtable, M_TEMP); 154 return (error); 155 } 156 #endif 157 158 #ifdef LINUX_GCC_SIGNATURE 159 /* 160 * Take advantage of the fact that all the linux binaries are compiled 161 * with gcc, and gcc sticks in the comment field a signature. Note that 162 * on SVR4 binaries, the gcc signature will follow the OS name signature, 163 * that will not be a problem. We don't bother to read in the string table, 164 * but we check all the progbits headers. 165 * 166 * XXX This only works in the i386. On the alpha (at least) 167 * XXX we have the same gcc signature which incorrectly identifies 168 * XXX NetBSD binaries as Linux. 169 */ 170 int 171 ELFNAME2(linux,gcc_signature)(l, epp, eh) 172 struct lwp *l; 173 struct exec_package *epp; 174 Elf_Ehdr *eh; 175 { 176 size_t shsize; 177 size_t i; 178 static const char signature[] = "\0GCC: (GNU) "; 179 char tbuf[sizeof(signature) - 1]; 180 Elf_Shdr *sh; 181 int error; 182 183 shsize = eh->e_shnum * sizeof(Elf_Shdr); 184 sh = (Elf_Shdr *) malloc(shsize, M_TEMP, M_WAITOK); 185 error = exec_read_from(l, epp->ep_vp, eh->e_shoff, sh, shsize); 186 if (error) 187 goto out; 188 189 for (i = 0; i < eh->e_shnum; i++) { 190 Elf_Shdr *s = &sh[i]; 191 192 /* 193 * Identify candidates for the comment header; 194 * Header cannot have a load address, or flags and 195 * it must be large enough. 196 */ 197 if (s->sh_type != SHT_PROGBITS || 198 s->sh_addr != 0 || 199 s->sh_flags != 0 || 200 s->sh_size < sizeof(signature) - 1) 201 continue; 202 203 error = exec_read_from(l, epp->ep_vp, s->sh_offset, tbuf, 204 sizeof(signature) - 1); 205 if (error) 206 continue; 207 208 /* 209 * error is 0, if the signatures match we are done. 210 */ 211 DPRINTF(("linux_gcc_sig: sig=%s\n", tbuf)); 212 if (!memcmp(tbuf, signature, sizeof(signature) - 1)) { 213 error = 0; 214 goto out; 215 } 216 } 217 error = ENOEXEC; 218 219 out: 220 free(sh, M_TEMP); 221 return (error); 222 } 223 #endif 224 225 #ifdef LINUX_DEBUGLINK_SIGNATURE 226 /* 227 * Look for a .gnu_debuglink, specific to x86_64 interpeter 228 */ 229 int 230 ELFNAME2(linux,debuglink_signature)(l, epp, eh) 231 struct lwp *l; 232 struct exec_package *epp; 233 Elf_Ehdr *eh; 234 { 235 size_t shsize; 236 int strndx; 237 size_t i; 238 static const char signature[] = ".gnu_debuglink"; 239 char *strtable = NULL; 240 Elf_Shdr *sh; 241 242 int error; 243 244 /* 245 * load the section header table 246 */ 247 shsize = eh->e_shnum * sizeof(Elf_Shdr); 248 sh = (Elf_Shdr *) malloc(shsize, M_TEMP, M_WAITOK); 249 error = exec_read_from(l, epp->ep_vp, eh->e_shoff, sh, shsize); 250 if (error) 251 goto out; 252 253 /* 254 * Now let's find the string table. If it does not exists, give up. 255 */ 256 strndx = (int)(eh->e_shstrndx); 257 if (strndx == SHN_UNDEF) { 258 error = ENOEXEC; 259 goto out; 260 } 261 262 /* 263 * strndx is the index in section header table of the string table 264 * section get the whole string table in strtable, and then we get access to the names 265 * s->sh_name is the offset of the section name in strtable. 266 */ 267 strtable = malloc(sh[strndx].sh_size, M_TEMP, M_WAITOK); 268 error = exec_read_from(l, epp->ep_vp, sh[strndx].sh_offset, strtable, 269 sh[strndx].sh_size); 270 if (error) 271 goto out; 272 273 for (i = 0; i < eh->e_shnum; i++) { 274 Elf_Shdr *s = &sh[i]; 275 276 if (!memcmp((void*)(&(strtable[s->sh_name])), signature, 277 sizeof(signature))) { 278 DPRINTF(("linux_debuglink_sig=%s\n", 279 &(strtable[s->sh_name]))); 280 error = 0; 281 goto out; 282 } 283 } 284 error = ENOEXEC; 285 286 out: 287 free(sh, M_TEMP); 288 if (strtable) 289 free(strtable, M_TEMP); 290 return (error); 291 } 292 #endif 293 294 int 295 ELFNAME2(linux,signature)(l, epp, eh, itp) 296 struct lwp *l; 297 struct exec_package *epp; 298 Elf_Ehdr *eh; 299 char *itp; 300 { 301 size_t i; 302 Elf_Phdr *ph; 303 size_t phsize; 304 int error; 305 static const char linux[] = "Linux"; 306 307 if (eh->e_ident[EI_OSABI] == 3 || 308 memcmp(&eh->e_ident[EI_ABIVERSION], linux, sizeof(linux)) == 0) 309 return 0; 310 311 phsize = eh->e_phnum * sizeof(Elf_Phdr); 312 ph = (Elf_Phdr *)malloc(phsize, M_TEMP, M_WAITOK); 313 error = exec_read_from(l, epp->ep_vp, eh->e_phoff, ph, phsize); 314 if (error) 315 goto out; 316 317 for (i = 0; i < eh->e_phnum; i++) { 318 Elf_Phdr *ephp = &ph[i]; 319 Elf_Nhdr *np; 320 u_int32_t *abi; 321 322 if (ephp->p_type != PT_NOTE || 323 ephp->p_filesz > 1024 || 324 ephp->p_filesz < sizeof(Elf_Nhdr) + 20) 325 continue; 326 327 np = (Elf_Nhdr *)malloc(ephp->p_filesz, M_TEMP, M_WAITOK); 328 error = exec_read_from(l, epp->ep_vp, ephp->p_offset, np, 329 ephp->p_filesz); 330 if (error) 331 goto next; 332 333 if (np->n_type != ELF_NOTE_TYPE_ABI_TAG || 334 np->n_namesz != ELF_NOTE_ABI_NAMESZ || 335 np->n_descsz != ELF_NOTE_ABI_DESCSZ || 336 memcmp((caddr_t)(np + 1), ELF_NOTE_ABI_NAME, 337 ELF_NOTE_ABI_NAMESZ)) 338 goto next; 339 340 /* Make sure the OS is Linux. */ 341 abi = (u_int32_t *)((caddr_t)np + sizeof(Elf_Nhdr) + 342 np->n_namesz); 343 if (abi[0] == ELF_NOTE_ABI_OS_LINUX) 344 error = 0; 345 else 346 error = ENOEXEC; 347 free(np, M_TEMP); 348 goto out; 349 350 next: 351 free(np, M_TEMP); 352 continue; 353 } 354 355 /* Check for certain intepreter names. */ 356 if (itp) { 357 if (!strncmp(itp, "/lib/ld-linux", 13) || 358 #if (ELFSIZE == 64) 359 !strncmp(itp, "/lib64/ld-linux", 15) || 360 #endif 361 !strncmp(itp, "/lib/ld.so.", 11)) 362 error = 0; 363 else 364 error = ENOEXEC; 365 goto out; 366 } 367 368 error = ENOEXEC; 369 out: 370 free(ph, M_TEMP); 371 return (error); 372 } 373 374 int 375 ELFNAME2(linux,probe)(l, epp, eh, itp, pos) 376 struct lwp *l; 377 struct exec_package *epp; 378 void *eh; 379 char *itp; 380 vaddr_t *pos; 381 { 382 int error; 383 384 if (((error = ELFNAME2(linux,signature)(l, epp, eh, itp)) != 0) && 385 #ifdef LINUX_GCC_SIGNATURE 386 ((error = ELFNAME2(linux,gcc_signature)(l, epp, eh)) != 0) && 387 #endif 388 #ifdef LINUX_ATEXIT_SIGNATURE 389 ((error = ELFNAME2(linux,atexit_signature)(l, epp, eh)) != 0) && 390 #endif 391 #ifdef LINUX_DEBUGLINK_SIGNATURE 392 ((error = ELFNAME2(linux,debuglink_signature)(l, epp, eh)) != 0) && 393 #endif 394 1) { 395 DPRINTF(("linux_probe: returning %d\n", error)); 396 return error; 397 } 398 399 if (itp) { 400 if ((error = emul_find_interp(l, epp->ep_esch->es_emul->e_path, 401 itp))) 402 return (error); 403 } 404 DPRINTF(("linux_probe: returning 0\n")); 405 return 0; 406 } 407 408 #ifndef LINUX_MACHDEP_ELF_COPYARGS 409 /* 410 * Copy arguments onto the stack in the normal way, but add some 411 * extra information in case of dynamic binding. 412 */ 413 int 414 ELFNAME2(linux,copyargs)(struct lwp *l, struct exec_package *pack, 415 struct ps_strings *arginfo, char **stackp, void *argp) 416 { 417 size_t len; 418 AuxInfo ai[LINUX_ELF_AUX_ENTRIES], *a; 419 struct elf_args *ap; 420 int error; 421 struct vattr *vap; 422 423 if ((error = copyargs(l, pack, arginfo, stackp, argp)) != 0) 424 return error; 425 426 a = ai; 427 428 /* 429 * Push extra arguments used by glibc on the stack. 430 */ 431 432 a->a_type = AT_PAGESZ; 433 a->a_v = PAGE_SIZE; 434 a++; 435 436 if ((ap = (struct elf_args *)pack->ep_emul_arg)) { 437 438 a->a_type = AT_PHDR; 439 a->a_v = ap->arg_phaddr; 440 a++; 441 442 a->a_type = AT_PHENT; 443 a->a_v = ap->arg_phentsize; 444 a++; 445 446 a->a_type = AT_PHNUM; 447 a->a_v = ap->arg_phnum; 448 a++; 449 450 a->a_type = AT_BASE; 451 a->a_v = ap->arg_interp; 452 a++; 453 454 a->a_type = AT_FLAGS; 455 a->a_v = 0; 456 a++; 457 458 a->a_type = AT_ENTRY; 459 a->a_v = ap->arg_entry; 460 a++; 461 462 free(pack->ep_emul_arg, M_TEMP); 463 pack->ep_emul_arg = NULL; 464 } 465 466 /* Linux-specific items */ 467 a->a_type = LINUX_AT_CLKTCK; 468 a->a_v = hz; 469 a++; 470 471 vap = pack->ep_vap; 472 473 a->a_type = LINUX_AT_UID; 474 a->a_v = kauth_cred_getuid(l->l_cred); 475 a++; 476 477 a->a_type = LINUX_AT_EUID; 478 if (vap->va_mode & S_ISUID) 479 a->a_v = vap->va_uid; 480 else 481 a->a_v = kauth_cred_geteuid(l->l_cred); 482 a++; 483 484 a->a_type = LINUX_AT_GID; 485 a->a_v = kauth_cred_getgid(l->l_cred); 486 a++; 487 488 a->a_type = LINUX_AT_EGID; 489 if (vap->va_mode & S_ISGID) 490 a->a_v = vap->va_gid; 491 else 492 a->a_v = kauth_cred_getegid(l->l_cred); 493 a++; 494 495 a->a_type = AT_NULL; 496 a->a_v = 0; 497 a++; 498 499 len = (a - ai) * sizeof(AuxInfo); 500 if ((error = copyout(ai, *stackp, len)) != 0) 501 return error; 502 *stackp += len; 503 504 return 0; 505 } 506 #endif /* !LINUX_MACHDEP_ELF_COPYARGS */ 507