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