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