1 /* $NetBSD: linux_exec_elf32.c,v 1.51 2001/01/19 01:43:31 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 #ifndef ELFSIZE 45 #define ELFSIZE 32 /* XXX should die */ 46 #endif 47 48 #include <sys/param.h> 49 #include <sys/systm.h> 50 #include <sys/kernel.h> 51 #include <sys/proc.h> 52 #include <sys/malloc.h> 53 #include <sys/namei.h> 54 #include <sys/vnode.h> 55 #include <sys/mount.h> 56 #include <sys/exec.h> 57 #include <sys/exec_elf.h> 58 59 #include <sys/mman.h> 60 #include <sys/syscallargs.h> 61 62 #include <machine/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 71 #include <compat/linux/linux_syscallargs.h> 72 #include <compat/linux/linux_syscall.h> 73 74 static int ELFNAME2(linux,signature) __P((struct proc *, struct exec_package *, 75 Elf_Ehdr *, char *)); 76 #ifdef LINUX_GCC_SIGNATURE 77 static int ELFNAME2(linux,gcc_signature) __P((struct proc *p, 78 struct exec_package *, Elf_Ehdr *)); 79 #endif 80 #ifdef LINUX_ATEXIT_SIGNATURE 81 static int ELFNAME2(linux,atexit_signature) __P((struct proc *p, 82 struct exec_package *, Elf_Ehdr *)); 83 #endif 84 85 #ifdef LINUX_ATEXIT_SIGNATURE 86 /* 87 * On the PowerPC, statically linked Linux binaries are not recognized 88 * by linux_signature nor by linux_gcc_signature. Fortunately, thoses 89 * binaries features a __libc_atexit ELF section. We therefore assume we 90 * have a Linux binary if we find this section. 91 */ 92 static int 93 ELFNAME2(linux,atexit_signature)(p, epp, eh) 94 struct proc *p; 95 struct exec_package *epp; 96 Elf_Ehdr *eh; 97 { 98 size_t shsize; 99 int strndx; 100 size_t i; 101 static const char signature[] = "__libc_atexit"; 102 char* strtable; 103 Elf_Shdr *sh; 104 105 int error; 106 107 /* 108 * load the section header table 109 */ 110 shsize = eh->e_shnum * sizeof(Elf_Shdr); 111 sh = (Elf_Shdr *) malloc(shsize, M_TEMP, M_WAITOK); 112 error = ELFNAME(read_from)(p, epp->ep_vp, eh->e_shoff, (caddr_t)sh, 113 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 section 128 * 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 = ELFNAME(read_from)(p, epp->ep_vp, sh[strndx].sh_offset, 133 (caddr_t)strtable, 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 #ifdef DEBUG_LINUX 142 printf("linux_atexit_sig=%s\n",&(strtable[s->sh_name])); 143 #endif 144 error = 0; 145 goto out; 146 } 147 } 148 error = ENOEXEC; 149 150 out: 151 free(sh, M_TEMP); 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 static int 170 ELFNAME2(linux,gcc_signature)(p, epp, eh) 171 struct proc *p; 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 buf[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 = ELFNAME(read_from)(p, epp->ep_vp, eh->e_shoff, (caddr_t)sh, 185 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 = ELFNAME(read_from)(p, epp->ep_vp, s->sh_offset, 204 (caddr_t)buf, sizeof(signature) - 1); 205 if (error) 206 continue; 207 208 /* 209 * error is 0, if the signatures match we are done. 210 */ 211 #ifdef DEBUG_LINUX 212 printf("linux_gcc_sig: sig=%s\n", buf); 213 #endif 214 if (!memcmp(buf, signature, sizeof(signature) - 1)) { 215 error = 0; 216 goto out; 217 } 218 } 219 error = ENOEXEC; 220 221 out: 222 free(sh, M_TEMP); 223 return (error); 224 } 225 #endif 226 227 static int 228 ELFNAME2(linux,signature)(p, epp, eh, itp) 229 struct proc *p; 230 struct exec_package *epp; 231 Elf_Ehdr *eh; 232 char *itp; 233 { 234 size_t i; 235 Elf_Phdr *ph; 236 size_t phsize; 237 int error; 238 239 phsize = eh->e_phnum * sizeof(Elf_Phdr); 240 ph = (Elf_Phdr *)malloc(phsize, M_TEMP, M_WAITOK); 241 error = ELFNAME(read_from)(p, epp->ep_vp, eh->e_phoff, (caddr_t)ph, 242 phsize); 243 if (error) 244 goto out; 245 246 for (i = 0; i < eh->e_phnum; i++) { 247 Elf_Phdr *ephp = &ph[i]; 248 Elf_Nhdr *np; 249 u_int32_t *abi; 250 251 if (ephp->p_type != PT_NOTE || 252 ephp->p_filesz > 1024 || 253 ephp->p_filesz < sizeof(Elf_Nhdr) + 20) 254 continue; 255 256 np = (Elf_Nhdr *)malloc(ephp->p_filesz, M_TEMP, M_WAITOK); 257 error = ELFNAME(read_from)(p, epp->ep_vp, ephp->p_offset, 258 (caddr_t)np, ephp->p_filesz); 259 if (error) 260 goto next; 261 262 if (np->n_type != ELF_NOTE_TYPE_ABI_TAG || 263 np->n_namesz != ELF_NOTE_ABI_NAMESZ || 264 np->n_descsz != ELF_NOTE_ABI_DESCSZ || 265 memcmp((caddr_t)(np + 1), ELF_NOTE_ABI_NAME, 266 ELF_NOTE_ABI_NAMESZ)) 267 goto next; 268 269 /* Make sure the OS is Linux. */ 270 abi = (u_int32_t *)((caddr_t)np + sizeof(Elf_Nhdr) + 271 np->n_namesz); 272 if (abi[0] == ELF_NOTE_ABI_OS_LINUX) 273 error = 0; 274 else 275 error = ENOEXEC; 276 free(np, M_TEMP); 277 goto out; 278 279 next: 280 free(np, M_TEMP); 281 continue; 282 } 283 284 /* Check for certain intepreter names. */ 285 if (itp[0]) { 286 if (!strncmp(itp, "/lib/ld-linux", 13) || 287 !strncmp(itp, "/lib/ld.so.", 11)) 288 error = 0; 289 else 290 error = ENOEXEC; 291 goto out; 292 } 293 294 error = ENOEXEC; 295 out: 296 free(ph, M_TEMP); 297 return (error); 298 } 299 300 int 301 ELFNAME2(linux,probe)(p, epp, eh, itp, pos) 302 struct proc *p; 303 struct exec_package *epp; 304 void *eh; 305 char *itp; 306 vaddr_t *pos; 307 { 308 const char *bp; 309 int error; 310 size_t len; 311 312 #ifdef LINUX_GCC_SIGNATURE 313 if ((error = ELFNAME2(linux,signature)(p, epp, eh, itp)) != 0) 314 if ((error = ELFNAME2(linux,gcc_signature)(p, epp, eh)) != 0) 315 return error; 316 #else 317 #ifdef LINUX_ATEXIT_SIGNATURE 318 if ((error = ELFNAME2(linux,signature)(p, epp, eh, itp)) != 0) 319 if ((error = ELFNAME2(linux,atexit_signature)(p, epp, eh)) != 0) 320 return error; 321 #else 322 if ((error = ELFNAME2(linux,signature)(p, epp, eh, itp)) != 0) 323 return error; 324 #endif 325 #endif 326 327 if (itp[0]) { 328 if ((error = emul_find(p, NULL, epp->ep_esch->es_emul->e_path, 329 itp, &bp, 0))) 330 return error; 331 if ((error = copystr(bp, itp, MAXPATHLEN, &len))) 332 return error; 333 free((void *)bp, M_TEMP); 334 } 335 *pos = ELF_NO_ADDR; 336 #ifdef DEBUG_LINUX 337 printf("linux_probe: returning 0\n"); 338 #endif 339 return 0; 340 } 341 342