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