1
2
3
4
5
6
7
8
9
10
11
12#include <linux/module.h>
13
14#include <linux/fs.h>
15#include <linux/stat.h>
16#include <linux/sched.h>
17#include <linux/mm.h>
18#include <linux/mman.h>
19#include <linux/a.out.h>
20#include <linux/errno.h>
21#include <linux/signal.h>
22#include <linux/binfmts.h>
23#include <linux/string.h>
24#include <linux/file.h>
25#include <linux/fcntl.h>
26#include <linux/ptrace.h>
27#include <linux/malloc.h>
28#include <linux/shm.h>
29#include <linux/personality.h>
30#include <linux/elfcore.h>
31#include <linux/init.h>
32
33#include <asm/uaccess.h>
34#include <asm/pgtable.h>
35
36#include <linux/config.h>
37
38#define DLINFO_ITEMS 13
39
40#include <linux/elf.h>
41
42static int load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs);
43static int load_elf_library(struct file *file);
44extern int dump_fpu (struct pt_regs *, elf_fpregset_t *);
45extern void dump_thread(struct pt_regs *, struct user *);
46
47#ifndef elf_addr_t
48#define elf_addr_t unsigned long
49#define elf_caddr_t char *
50#endif
51
52
53
54
55
56#ifdef USE_ELF_CORE_DUMP
57static int elf_core_dump(long signr, struct pt_regs * regs, struct file *);
58#else
59#define elf_core_dump NULL
60#endif
61
62#define ELF_PAGESTART(_v) ((_v) & ~(unsigned long)(ELF_EXEC_PAGESIZE-1))
63#define ELF_PAGEOFFSET(_v) ((_v) & (ELF_EXEC_PAGESIZE-1))
64#define ELF_PAGEALIGN(_v) (((_v) + ELF_EXEC_PAGESIZE - 1) & ~(ELF_EXEC_PAGESIZE - 1))
65
66static struct linux_binfmt elf_format = {
67 module: THIS_MODULE,
68 load_binary: load_elf_binary,
69 load_shlib: load_elf_library,
70 core_dump: elf_core_dump,
71 min_coredump: ELF_EXEC_PAGESIZE,
72};
73
74static void set_brk(unsigned long start, unsigned long end)
75{
76 start = ELF_PAGEALIGN(start);
77 end = ELF_PAGEALIGN(end);
78 if (end <= start)
79 return;
80 do_mmap(NULL, start, end - start,
81 PROT_READ | PROT_WRITE | PROT_EXEC,
82 MAP_FIXED | MAP_PRIVATE, 0);
83}
84
85
86
87
88
89
90
91
92static void padzero(unsigned long elf_bss)
93{
94 unsigned long nbyte;
95
96 nbyte = ELF_PAGEOFFSET(elf_bss);
97 if (nbyte) {
98 nbyte = ELF_EXEC_PAGESIZE - nbyte;
99 clear_user((void *) elf_bss, nbyte);
100 }
101}
102
103static elf_addr_t *
104create_elf_tables(char *p, int argc, int envc,
105 struct elfhdr * exec,
106 unsigned long load_addr,
107 unsigned long load_bias,
108 unsigned long interp_load_addr, int ibcs)
109{
110 elf_caddr_t *argv;
111 elf_caddr_t *envp;
112 elf_addr_t *sp, *csp;
113 char *k_platform, *u_platform;
114 long hwcap;
115 size_t platform_len = 0;
116 long len;
117
118
119
120
121
122
123
124
125 hwcap = ELF_HWCAP;
126 k_platform = ELF_PLATFORM;
127
128 if (k_platform) {
129 platform_len = strlen(k_platform) + 1;
130 u_platform = p - platform_len;
131 __copy_to_user(u_platform, k_platform, platform_len);
132 } else
133 u_platform = p;
134
135
136
137
138
139
140 sp = (elf_addr_t *)((~15UL & (unsigned long)(u_platform)) - 16UL);
141 csp = sp;
142 csp -= ((exec ? DLINFO_ITEMS*2 : 4) + (k_platform ? 2 : 0));
143 csp -= envc+1;
144 csp -= argc+1;
145 csp -= (!ibcs ? 3 : 1);
146 if ((unsigned long)csp & 15UL)
147 sp -= ((unsigned long)csp & 15UL) / sizeof(*sp);
148
149
150
151
152#define NEW_AUX_ENT(nr, id, val) \
153 __put_user ((id), sp+(nr*2)); \
154 __put_user ((val), sp+(nr*2+1)); \
155
156 sp -= 2;
157 NEW_AUX_ENT(0, AT_NULL, 0);
158 if (k_platform) {
159 sp -= 2;
160 NEW_AUX_ENT(0, AT_PLATFORM, (elf_addr_t)(unsigned long) u_platform);
161 }
162 sp -= 2;
163 NEW_AUX_ENT(0, AT_HWCAP, hwcap);
164
165 if (exec) {
166 sp -= 11*2;
167
168 NEW_AUX_ENT(0, AT_PHDR, load_addr + exec->e_phoff);
169 NEW_AUX_ENT(1, AT_PHENT, sizeof (struct elf_phdr));
170 NEW_AUX_ENT(2, AT_PHNUM, exec->e_phnum);
171 NEW_AUX_ENT(3, AT_PAGESZ, ELF_EXEC_PAGESIZE);
172 NEW_AUX_ENT(4, AT_BASE, interp_load_addr);
173 NEW_AUX_ENT(5, AT_FLAGS, 0);
174 NEW_AUX_ENT(6, AT_ENTRY, load_bias + exec->e_entry);
175 NEW_AUX_ENT(7, AT_UID, (elf_addr_t) current->uid);
176 NEW_AUX_ENT(8, AT_EUID, (elf_addr_t) current->euid);
177 NEW_AUX_ENT(9, AT_GID, (elf_addr_t) current->gid);
178 NEW_AUX_ENT(10, AT_EGID, (elf_addr_t) current->egid);
179 }
180#undef NEW_AUX_ENT
181
182 sp -= envc+1;
183 envp = (elf_caddr_t *) sp;
184 sp -= argc+1;
185 argv = (elf_caddr_t *) sp;
186 if (!ibcs) {
187 __put_user((elf_addr_t)(unsigned long) envp,--sp);
188 __put_user((elf_addr_t)(unsigned long) argv,--sp);
189 }
190
191 __put_user((elf_addr_t)argc,--sp);
192 current->mm->arg_start = (unsigned long) p;
193 while (argc-->0) {
194 __put_user((elf_caddr_t)(unsigned long)p,argv++);
195 len = strnlen_user(p, PAGE_SIZE*MAX_ARG_PAGES);
196
197 if (!len || len > PAGE_SIZE*MAX_ARG_PAGES)
198 return NULL;
199 p += len;
200 }
201 __put_user(NULL, argv);
202 current->mm->arg_end = current->mm->env_start = (unsigned long) p;
203 while (envc-->0) {
204 __put_user((elf_caddr_t)(unsigned long)p,envp++);
205 len = strnlen_user(p, PAGE_SIZE*MAX_ARG_PAGES);
206
207 if (!len || len > PAGE_SIZE*MAX_ARG_PAGES)
208 return NULL;
209 p += len;
210 }
211 __put_user(NULL, envp);
212 current->mm->env_end = (unsigned long) p;
213 return sp;
214}
215
216
217
218
219
220
221
222static unsigned long load_elf_interp(struct elfhdr * interp_elf_ex,
223 struct dentry * interpreter_dentry,
224 unsigned long *interp_load_addr)
225{
226 struct file * file;
227 struct elf_phdr *elf_phdata;
228 struct elf_phdr *eppnt;
229 unsigned long load_addr = 0;
230 int load_addr_set = 0;
231 unsigned long last_bss = 0, elf_bss = 0;
232 unsigned long error = ~0UL;
233 int elf_exec_fileno;
234 int retval, i, size;
235
236
237 if (interp_elf_ex->e_type != ET_EXEC &&
238 interp_elf_ex->e_type != ET_DYN)
239 goto out;
240 if (!elf_check_arch(interp_elf_ex->e_machine))
241 goto out;
242 if (!interpreter_dentry->d_inode->i_op ||
243 !interpreter_dentry->d_inode->i_op->default_file_ops->mmap)
244 goto out;
245
246
247
248
249
250 if (interp_elf_ex->e_phentsize != sizeof(struct elf_phdr))
251 goto out;
252
253
254
255 if (interp_elf_ex->e_phnum < 1 || interp_elf_ex->e_phnum >
256 ELF_EXEC_PAGESIZE / sizeof(struct elf_phdr))
257 goto out;
258 size = sizeof(struct elf_phdr) * interp_elf_ex->e_phnum;
259 elf_phdata = (struct elf_phdr *) kmalloc(size, GFP_KERNEL);
260 if (!elf_phdata)
261 goto out;
262
263 retval = read_exec(interpreter_dentry, interp_elf_ex->e_phoff,
264 (char *) elf_phdata, size, 1);
265 error = retval;
266 if (retval < 0)
267 goto out_free;
268
269 error = ~0UL;
270 elf_exec_fileno = open_dentry(interpreter_dentry, O_RDONLY);
271 if (elf_exec_fileno < 0)
272 goto out_free;
273 file = fget(elf_exec_fileno);
274
275 eppnt = elf_phdata;
276 for (i=0; i<interp_elf_ex->e_phnum; i++, eppnt++) {
277 if (eppnt->p_type == PT_LOAD) {
278 int elf_type = MAP_PRIVATE | MAP_DENYWRITE;
279 int elf_prot = 0;
280 unsigned long vaddr = 0;
281 unsigned long k, map_addr;
282
283 if (eppnt->p_flags & PF_R) elf_prot = PROT_READ;
284 if (eppnt->p_flags & PF_W) elf_prot |= PROT_WRITE;
285 if (eppnt->p_flags & PF_X) elf_prot |= PROT_EXEC;
286 vaddr = eppnt->p_vaddr;
287 if (interp_elf_ex->e_type == ET_EXEC || load_addr_set) {
288 elf_type |= MAP_FIXED;
289#ifdef __sparc__
290 } else {
291 load_addr = get_unmapped_area(0, eppnt->p_filesz +
292 ELF_PAGEOFFSET(vaddr));
293#endif
294 }
295
296 map_addr = do_mmap(file,
297 load_addr + ELF_PAGESTART(vaddr),
298 eppnt->p_filesz + ELF_PAGEOFFSET(eppnt->p_vaddr),
299 elf_prot,
300 elf_type,
301 eppnt->p_offset - ELF_PAGEOFFSET(eppnt->p_vaddr));
302 if (map_addr > -1024UL)
303 goto out_close;
304
305 if (!load_addr_set && interp_elf_ex->e_type == ET_DYN) {
306 load_addr = map_addr - ELF_PAGESTART(vaddr);
307 load_addr_set = 1;
308 }
309
310
311
312
313
314 k = load_addr + eppnt->p_vaddr + eppnt->p_filesz;
315 if (k > elf_bss)
316 elf_bss = k;
317
318
319
320
321
322 k = load_addr + eppnt->p_memsz + eppnt->p_vaddr;
323 if (k > last_bss)
324 last_bss = k;
325 }
326 }
327
328
329
330
331
332
333
334
335
336 padzero(elf_bss);
337 elf_bss = ELF_PAGESTART(elf_bss + ELF_EXEC_PAGESIZE - 1);
338
339
340 if (last_bss > elf_bss)
341 do_mmap(NULL, elf_bss, last_bss - elf_bss,
342 PROT_READ|PROT_WRITE|PROT_EXEC,
343 MAP_FIXED|MAP_PRIVATE, 0);
344
345 *interp_load_addr = load_addr;
346
347
348
349
350
351 error = ((unsigned long) interp_elf_ex->e_entry) + load_addr;
352
353out_close:
354 fput(file);
355 sys_close(elf_exec_fileno);
356out_free:
357 kfree(elf_phdata);
358out:
359 return error;
360}
361
362static unsigned long load_aout_interp(struct exec * interp_ex,
363 struct dentry * interpreter_dentry)
364{
365 unsigned long text_data, offset, elf_entry = ~0UL;
366 char * addr;
367 int retval;
368
369 current->mm->end_code = interp_ex->a_text;
370 text_data = interp_ex->a_text + interp_ex->a_data;
371 current->mm->end_data = text_data;
372 current->mm->brk = interp_ex->a_bss + text_data;
373
374 switch (N_MAGIC(*interp_ex)) {
375 case OMAGIC:
376 offset = 32;
377 addr = (char *) 0;
378 break;
379 case ZMAGIC:
380 case QMAGIC:
381 offset = N_TXTOFF(*interp_ex);
382 addr = (char *) N_TXTADDR(*interp_ex);
383 break;
384 default:
385 goto out;
386 }
387
388 if ((unsigned long)addr + text_data < text_data)
389 goto out;
390
391 do_mmap(NULL, 0, text_data,
392 PROT_READ|PROT_WRITE|PROT_EXEC, MAP_FIXED|MAP_PRIVATE, 0);
393 retval = read_exec(interpreter_dentry, offset, addr, text_data, 0);
394 if (retval < 0)
395 goto out;
396 flush_icache_range((unsigned long)addr,
397 (unsigned long)addr + text_data);
398
399 do_mmap(NULL, ELF_PAGESTART(text_data + ELF_EXEC_PAGESIZE - 1),
400 interp_ex->a_bss,
401 PROT_READ|PROT_WRITE|PROT_EXEC, MAP_FIXED|MAP_PRIVATE, 0);
402 elf_entry = interp_ex->a_entry;
403
404out:
405 return elf_entry;
406}
407
408
409
410
411
412
413#define INTERPRETER_NONE 0
414#define INTERPRETER_AOUT 1
415#define INTERPRETER_ELF 2
416
417
418static int load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs)
419{
420 struct file * file;
421 struct dentry *interpreter_dentry = NULL;
422 unsigned long load_addr = 0, load_bias;
423 int load_addr_set = 0;
424 char * elf_interpreter = NULL;
425 unsigned int interpreter_type = INTERPRETER_NONE;
426 unsigned char ibcs2_interpreter = 0;
427 mm_segment_t old_fs;
428 unsigned long error;
429 struct elf_phdr * elf_ppnt, *elf_phdata;
430 unsigned long elf_bss, k, elf_brk;
431 int elf_exec_fileno;
432 int retval, size, i;
433 unsigned long elf_entry, interp_load_addr = 0;
434 unsigned long start_code, end_code, end_data;
435 struct elfhdr elf_ex;
436 struct elfhdr interp_elf_ex;
437 struct exec interp_ex;
438 char passed_fileno[6];
439
440
441 elf_ex = *((struct elfhdr *) bprm->buf);
442
443 retval = -ENOEXEC;
444
445 if (elf_ex.e_ident[0] != 0x7f ||
446 strncmp(&elf_ex.e_ident[1], "ELF", 3) != 0)
447 goto out;
448
449 if (elf_ex.e_type != ET_EXEC && elf_ex.e_type != ET_DYN)
450 goto out;
451 if (!elf_check_arch(elf_ex.e_machine))
452 goto out;
453#ifdef __mips__
454
455 if (elf_ex.e_flags & EF_MIPS_ARCH) {
456 retval = -ENOEXEC;
457 goto out;
458 }
459#endif
460 if (!bprm->dentry->d_inode->i_op ||
461 !bprm->dentry->d_inode->i_op->default_file_ops ||
462 !bprm->dentry->d_inode->i_op->default_file_ops->mmap)
463 goto out;
464
465
466
467 if (elf_ex.e_phentsize != sizeof(struct elf_phdr) ||
468 elf_ex.e_phnum < 1 ||
469 elf_ex.e_phnum > 65536 / sizeof(struct elf_phdr))
470 goto out;
471
472 retval = -ENOMEM;
473 size = elf_ex.e_phentsize * elf_ex.e_phnum;
474 elf_phdata = (struct elf_phdr *) kmalloc(size, GFP_KERNEL);
475 if (!elf_phdata)
476 goto out;
477
478 retval = read_exec(bprm->dentry, elf_ex.e_phoff,
479 (char *) elf_phdata, size, 1);
480 if (retval < 0)
481 goto out_free_ph;
482
483 retval = open_dentry(bprm->dentry, O_RDONLY);
484 if (retval < 0)
485 goto out_free_ph;
486 elf_exec_fileno = retval;
487 file = fget(elf_exec_fileno);
488
489 elf_ppnt = elf_phdata;
490 elf_bss = 0;
491 elf_brk = 0;
492
493 start_code = ~0UL;
494 end_code = 0;
495 end_data = 0;
496
497 for (i = 0; i < elf_ex.e_phnum; i++) {
498 if (elf_ppnt->p_type == PT_INTERP) {
499 retval = -ENOEXEC;
500 if (elf_interpreter ||
501 elf_ppnt->p_filesz < 2 ||
502 elf_ppnt->p_filesz > PAGE_SIZE)
503 goto out_free_dentry;
504
505
506
507
508
509
510 retval = -ENOMEM;
511 elf_interpreter = (char *) kmalloc(elf_ppnt->p_filesz,
512 GFP_KERNEL);
513 if (!elf_interpreter)
514 goto out_free_file;
515
516 retval = read_exec(bprm->dentry, elf_ppnt->p_offset,
517 elf_interpreter,
518 elf_ppnt->p_filesz, 1);
519 if (retval < 0)
520 goto out_free_interp;
521 elf_interpreter[elf_ppnt->p_filesz - 1] = 0;
522
523
524
525
526 if (strcmp(elf_interpreter,"/usr/lib/libc.so.1") == 0 ||
527 strcmp(elf_interpreter,"/usr/lib/ld.so.1") == 0)
528 ibcs2_interpreter = 1;
529#if 0
530 printk("Using ELF interpreter %s\n", elf_interpreter);
531#endif
532 old_fs = get_fs();
533 set_fs(get_ds());
534#ifdef __sparc__
535 if (ibcs2_interpreter) {
536 unsigned long old_pers = current->personality;
537
538 current->personality = PER_SVR4;
539 interpreter_dentry = open_namei(elf_interpreter,
540 1, 0);
541 current->personality = old_pers;
542 } else
543#endif
544 interpreter_dentry = open_namei(elf_interpreter,
545 1, 0);
546 set_fs(old_fs);
547 retval = PTR_ERR(interpreter_dentry);
548 if (IS_ERR(interpreter_dentry))
549 goto out_free_interp;
550 retval = permission(interpreter_dentry->d_inode, MAY_EXEC);
551 if (retval < 0)
552 goto out_free_dentry;
553 retval = read_exec(interpreter_dentry, 0, bprm->buf, 128, 1);
554 if (retval < 0)
555 goto out_free_dentry;
556
557
558 interp_ex = *((struct exec *) bprm->buf);
559 interp_elf_ex = *((struct elfhdr *) bprm->buf);
560 }
561 elf_ppnt++;
562 }
563
564
565 if (elf_interpreter) {
566 interpreter_type = INTERPRETER_ELF | INTERPRETER_AOUT;
567
568
569 if ((N_MAGIC(interp_ex) != OMAGIC) &&
570 (N_MAGIC(interp_ex) != ZMAGIC) &&
571 (N_MAGIC(interp_ex) != QMAGIC))
572 interpreter_type = INTERPRETER_ELF;
573
574 if (interp_elf_ex.e_ident[0] != 0x7f ||
575 strncmp(&interp_elf_ex.e_ident[1], "ELF", 3) != 0)
576 interpreter_type &= ~INTERPRETER_ELF;
577
578 retval = -ELIBBAD;
579 if (!interpreter_type)
580 goto out_free_dentry;
581
582
583 if ((interpreter_type & INTERPRETER_ELF) &&
584 interpreter_type != INTERPRETER_ELF) {
585 printk(KERN_WARNING "ELF: Ambiguous type, using ELF\n");
586 interpreter_type = INTERPRETER_ELF;
587 }
588 }
589
590
591
592
593 if (!bprm->sh_bang) {
594 char * passed_p;
595
596 if (interpreter_type == INTERPRETER_AOUT) {
597 sprintf(passed_fileno, "%d", elf_exec_fileno);
598 passed_p = passed_fileno;
599
600 if (elf_interpreter) {
601 bprm->p = copy_strings(1,&passed_p,bprm->page,bprm->p,2);
602 bprm->argc++;
603 }
604 }
605 retval = (long)bprm->p;
606 if ((long)bprm->p < 0)
607 goto out_free_dentry;
608 }
609
610
611 retval = flush_old_exec(bprm);
612 if (retval)
613 goto out_free_dentry;
614
615
616 current->mm->end_data = 0;
617 current->mm->end_code = 0;
618 current->mm->mmap = NULL;
619 current->flags &= ~PF_FORKNOEXEC;
620 elf_entry = (unsigned long) elf_ex.e_entry;
621
622
623
624 SET_PERSONALITY(elf_ex, ibcs2_interpreter);
625
626
627
628 current->mm->rss = 0;
629 bprm->p = setup_arg_pages(bprm->p, bprm);
630 current->mm->start_stack = bprm->p;
631
632
633
634
635
636 load_bias = ELF_PAGESTART(elf_ex.e_type==ET_DYN ? ELF_ET_DYN_BASE : 0);
637
638
639
640
641
642
643 old_fs = get_fs();
644 set_fs(get_ds());
645 for(i = 0, elf_ppnt = elf_phdata; i < elf_ex.e_phnum; i++, elf_ppnt++) {
646 int elf_prot = 0, elf_flags;
647 unsigned long vaddr;
648
649 if (elf_ppnt->p_type != PT_LOAD)
650 continue;
651
652 if (elf_ppnt->p_flags & PF_R) elf_prot |= PROT_READ;
653 if (elf_ppnt->p_flags & PF_W) elf_prot |= PROT_WRITE;
654 if (elf_ppnt->p_flags & PF_X) elf_prot |= PROT_EXEC;
655
656 elf_flags = MAP_PRIVATE|MAP_DENYWRITE|MAP_EXECUTABLE;
657
658 vaddr = elf_ppnt->p_vaddr;
659 if (elf_ex.e_type == ET_EXEC || load_addr_set) {
660 elf_flags |= MAP_FIXED;
661 }
662
663 error = do_mmap(file, ELF_PAGESTART(load_bias + vaddr),
664 (elf_ppnt->p_filesz +
665 ELF_PAGEOFFSET(elf_ppnt->p_vaddr)),
666 elf_prot, elf_flags, (elf_ppnt->p_offset -
667 ELF_PAGEOFFSET(elf_ppnt->p_vaddr)));
668
669 if (!load_addr_set) {
670 load_addr_set = 1;
671 load_addr = (elf_ppnt->p_vaddr - elf_ppnt->p_offset);
672 if (elf_ex.e_type == ET_DYN) {
673 load_bias += error -
674 ELF_PAGESTART(load_bias + vaddr);
675 load_addr += load_bias;
676 }
677 }
678 k = elf_ppnt->p_vaddr;
679 if (k < start_code) start_code = k;
680 k = elf_ppnt->p_vaddr + elf_ppnt->p_filesz;
681 if (k > elf_bss)
682 elf_bss = k;
683 if ((elf_ppnt->p_flags & PF_X) && end_code < k)
684 end_code = k;
685 if (end_data < k)
686 end_data = k;
687 k = elf_ppnt->p_vaddr + elf_ppnt->p_memsz;
688 if (k > elf_brk)
689 elf_brk = k;
690 }
691 set_fs(old_fs);
692 fput(file);
693
694 elf_entry += load_bias;
695 elf_bss += load_bias;
696 elf_brk += load_bias;
697 start_code += load_bias;
698 end_code += load_bias;
699 end_data += load_bias;
700
701 if (elf_interpreter) {
702 if (interpreter_type == INTERPRETER_AOUT)
703 elf_entry = load_aout_interp(&interp_ex,
704 interpreter_dentry);
705 else
706 elf_entry = load_elf_interp(&interp_elf_ex,
707 interpreter_dentry,
708 &interp_load_addr);
709
710 dput(interpreter_dentry);
711
712 if (elf_entry == ~0UL) {
713 printk(KERN_ERR "Unable to load interpreter %.128s\n",
714 elf_interpreter);
715 kfree(elf_interpreter);
716 kfree(elf_phdata);
717 force_sig(SIGSEGV, current);
718 return 0;
719 }
720
721 kfree(elf_interpreter);
722 }
723
724 kfree(elf_phdata);
725
726 if (interpreter_type != INTERPRETER_AOUT)
727 sys_close(elf_exec_fileno);
728
729 set_binfmt(&elf_format);
730 if (current->exec_domain && current->exec_domain->module)
731 __MOD_DEC_USE_COUNT(current->exec_domain->module);
732 current->exec_domain = lookup_exec_domain(current->personality);
733 if (current->exec_domain && current->exec_domain->module)
734 __MOD_INC_USE_COUNT(current->exec_domain->module);
735
736 compute_creds(bprm);
737 current->flags &= ~PF_FORKNOEXEC;
738 bprm->p = (unsigned long)
739 create_elf_tables((char *)bprm->p,
740 bprm->argc,
741 bprm->envc,
742 (interpreter_type == INTERPRETER_ELF ? &elf_ex : NULL),
743 load_addr, load_bias,
744 interp_load_addr,
745 (interpreter_type == INTERPRETER_AOUT ? 0 : 1));
746 if (!bprm->p) {
747 force_sig(SIGSEGV, current);
748 return 0;
749 }
750
751 if (interpreter_type == INTERPRETER_AOUT)
752 current->mm->arg_start += strlen(passed_fileno) + 1;
753 current->mm->start_brk = current->mm->brk = elf_brk;
754 current->mm->end_code = end_code;
755 current->mm->start_code = start_code;
756 current->mm->end_data = end_data;
757 current->mm->start_stack = bprm->p;
758
759
760
761
762 set_brk(elf_bss, elf_brk);
763
764 padzero(elf_bss);
765
766#if 0
767 printk("(start_brk) %x\n" , current->mm->start_brk);
768 printk("(end_code) %x\n" , current->mm->end_code);
769 printk("(start_code) %x\n" , current->mm->start_code);
770 printk("(end_data) %x\n" , current->mm->end_data);
771 printk("(start_stack) %x\n" , current->mm->start_stack);
772 printk("(brk) %x\n" , current->mm->brk);
773#endif
774
775 if ( current->personality == PER_SVR4 )
776 {
777
778
779
780
781
782 error = do_mmap(NULL, 0, 4096, PROT_READ | PROT_EXEC,
783 MAP_FIXED | MAP_PRIVATE, 0);
784 }
785
786#ifdef ELF_PLAT_INIT
787
788
789
790
791
792
793 ELF_PLAT_INIT(regs);
794#endif
795
796 start_thread(regs, elf_entry, bprm->p);
797 if (current->ptrace & PT_PTRACED)
798 send_sig(SIGTRAP, current, 0);
799 retval = 0;
800out:
801 return retval;
802
803
804out_free_dentry:
805 dput(interpreter_dentry);
806out_free_interp:
807 if (elf_interpreter)
808 kfree(elf_interpreter);
809out_free_file:
810 fput(file);
811 sys_close(elf_exec_fileno);
812out_free_ph:
813 kfree(elf_phdata);
814 goto out;
815}
816
817
818
819
820static int load_elf_library(struct file *file)
821{
822 struct dentry * dentry;
823 struct inode * inode;
824 struct elf_phdr *elf_phdata;
825 unsigned long elf_bss = 0, bss, len, k;
826 int retval, error, i, j;
827 struct elfhdr elf_ex;
828 loff_t offset = 0;
829
830 dentry = file->f_dentry;
831 inode = dentry->d_inode;
832
833
834 error = -ENOEXEC;
835
836
837 set_fs(KERNEL_DS);
838 retval = file->f_op->read(file, (char *) &elf_ex, sizeof(elf_ex), &offset);
839 set_fs(USER_DS);
840 if (retval != sizeof(elf_ex))
841 goto out_putf;
842
843 if (elf_ex.e_ident[0] != 0x7f ||
844 strncmp(&elf_ex.e_ident[1], "ELF", 3) != 0)
845 goto out_putf;
846
847
848 if (elf_ex.e_type != ET_EXEC || elf_ex.e_phnum > 2 ||
849 !elf_check_arch(elf_ex.e_machine) ||
850 (!inode->i_op || !inode->i_op->default_file_ops->mmap))
851 goto out_putf;
852
853
854
855 j = sizeof(struct elf_phdr) * elf_ex.e_phnum;
856 if (j > ELF_EXEC_PAGESIZE)
857 goto out_putf;
858
859 error = -ENOMEM;
860 elf_phdata = (struct elf_phdr *) kmalloc(j, GFP_KERNEL);
861 if (!elf_phdata)
862 goto out_putf;
863
864
865 retval = read_exec(dentry, elf_ex.e_phoff, (char *) elf_phdata,
866 sizeof(struct elf_phdr) * elf_ex.e_phnum, 1);
867
868 error = -ENOEXEC;
869 for (j = 0, i = 0; i<elf_ex.e_phnum; i++)
870 if ((elf_phdata + i)->p_type == PT_LOAD) j++;
871 if (j != 1)
872 goto out_free_ph;
873
874 while (elf_phdata->p_type != PT_LOAD) elf_phdata++;
875
876
877 error = do_mmap(file,
878 ELF_PAGESTART(elf_phdata->p_vaddr),
879 (elf_phdata->p_filesz +
880 ELF_PAGEOFFSET(elf_phdata->p_vaddr)),
881 PROT_READ | PROT_WRITE | PROT_EXEC,
882 MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE,
883 (elf_phdata->p_offset -
884 ELF_PAGEOFFSET(elf_phdata->p_vaddr)));
885 if (error != ELF_PAGESTART(elf_phdata->p_vaddr))
886 goto out_free_ph;
887
888 k = elf_phdata->p_vaddr + elf_phdata->p_filesz;
889 if (k > elf_bss)
890 elf_bss = k;
891 padzero(elf_bss);
892
893 len = ELF_PAGESTART(elf_phdata->p_filesz + elf_phdata->p_vaddr +
894 ELF_EXEC_PAGESIZE - 1);
895 bss = elf_phdata->p_memsz + elf_phdata->p_vaddr;
896 if (bss > len)
897 do_mmap(NULL, len, bss - len,
898 PROT_READ|PROT_WRITE|PROT_EXEC,
899 MAP_FIXED|MAP_PRIVATE, 0);
900 error = 0;
901
902out_free_ph:
903 kfree(elf_phdata);
904out_putf:
905 return error;
906}
907
908
909
910
911
912#ifdef USE_ELF_CORE_DUMP
913
914
915
916
917
918
919
920
921
922
923
924static int dump_write(struct file *file, const void *addr, int nr)
925{
926 int r;
927 fs_down(&file->f_dentry->d_inode->i_sem);
928 r = file->f_op->write(file, addr, nr, &file->f_pos) == nr;
929 fs_up(&file->f_dentry->d_inode->i_sem);
930 return r;
931}
932
933static int dump_seek(struct file *file, off_t off)
934{
935 if (file->f_op->llseek) {
936 if (file->f_op->llseek(file, off, 0) != off)
937 return 0;
938 } else
939 file->f_pos = off;
940 return 1;
941}
942
943
944
945
946
947
948
949
950static inline int maydump(struct vm_area_struct *vma)
951{
952 if (!(vma->vm_flags & (VM_READ|VM_WRITE|VM_EXEC)))
953 return 0;
954
955
956 if(vma->vm_flags & VM_IO)
957 return 0;
958#if 1
959 if (vma->vm_flags & (VM_WRITE|VM_GROWSUP|VM_GROWSDOWN))
960 return 1;
961 if (vma->vm_flags & (VM_READ|VM_EXEC|VM_EXECUTABLE|VM_SHARED))
962 return 0;
963#endif
964 return 1;
965}
966
967#define roundup(x, y) ((((x)+((y)-1))/(y))*(y))
968
969
970struct memelfnote
971{
972 const char *name;
973 int type;
974 unsigned int datasz;
975 void *data;
976};
977
978static int notesize(struct memelfnote *en)
979{
980 int sz;
981
982 sz = sizeof(struct elf_note);
983 sz += roundup(strlen(en->name), 4);
984 sz += roundup(en->datasz, 4);
985
986 return sz;
987}
988
989
990
991#ifdef DEBUG
992static void dump_regs(const char *str, elf_greg_t *r)
993{
994 int i;
995 static const char *regs[] = { "ebx", "ecx", "edx", "esi", "edi", "ebp",
996 "eax", "ds", "es", "fs", "gs",
997 "orig_eax", "eip", "cs",
998 "efl", "uesp", "ss"};
999 printk("Registers: %s\n", str);
1000
1001 for(i = 0; i < ELF_NGREG; i++)
1002 {
1003 unsigned long val = r[i];
1004 printk(" %-2d %-5s=%08lx %lu\n", i, regs[i], val, val);
1005 }
1006}
1007#endif
1008
1009#define DUMP_WRITE(addr, nr) \
1010 do { if (!dump_write(file, (addr), (nr))) return 0; } while(0)
1011#define DUMP_SEEK(off) \
1012 do { if (!dump_seek(file, (off))) return 0; } while(0)
1013
1014static int writenote(struct memelfnote *men, struct file *file)
1015{
1016 struct elf_note en;
1017
1018 en.n_namesz = strlen(men->name);
1019 en.n_descsz = men->datasz;
1020 en.n_type = men->type;
1021
1022 DUMP_WRITE(&en, sizeof(en));
1023 DUMP_WRITE(men->name, en.n_namesz);
1024
1025 DUMP_SEEK(roundup((unsigned long)file->f_pos, 4));
1026 DUMP_WRITE(men->data, men->datasz);
1027 DUMP_SEEK(roundup((unsigned long)file->f_pos, 4));
1028
1029 return 1;
1030}
1031#undef DUMP_WRITE
1032#undef DUMP_SEEK
1033
1034#define DUMP_WRITE(addr, nr) \
1035 if ((size += (nr)) > limit || !dump_write(file, (addr), (nr))) \
1036 goto close_coredump;
1037#define DUMP_SEEK(off) \
1038 if (!dump_seek(file, (off))) \
1039 goto close_coredump;
1040
1041
1042
1043
1044
1045
1046
1047static int elf_core_dump(long signr, struct pt_regs * regs, struct file * file)
1048{
1049 int has_dumped = 0;
1050 mm_segment_t fs;
1051 int segs;
1052 int i;
1053 size_t size = 0;
1054 struct vm_area_struct *vma;
1055 struct elfhdr elf;
1056 off_t offset = 0, dataoff;
1057 unsigned long limit = current->rlim[RLIMIT_CORE].rlim_cur;
1058 int numnote = 4;
1059 struct memelfnote notes[4];
1060 struct elf_prstatus prstatus;
1061 elf_fpregset_t fpu;
1062 struct elf_prpsinfo psinfo;
1063
1064 segs = current->mm->map_count;
1065
1066#ifdef DEBUG
1067 printk("elf_core_dump: %d segs %lu limit\n", segs, limit);
1068#endif
1069
1070
1071 memcpy(elf.e_ident, ELFMAG, SELFMAG);
1072 elf.e_ident[EI_CLASS] = ELF_CLASS;
1073 elf.e_ident[EI_DATA] = ELF_DATA;
1074 elf.e_ident[EI_VERSION] = EV_CURRENT;
1075 memset(elf.e_ident+EI_PAD, 0, EI_NIDENT-EI_PAD);
1076
1077 elf.e_type = ET_CORE;
1078 elf.e_machine = ELF_ARCH;
1079 elf.e_version = EV_CURRENT;
1080 elf.e_entry = 0;
1081 elf.e_phoff = sizeof(elf);
1082 elf.e_shoff = 0;
1083 elf.e_flags = 0;
1084 elf.e_ehsize = sizeof(elf);
1085 elf.e_phentsize = sizeof(struct elf_phdr);
1086 elf.e_phnum = segs+1;
1087 elf.e_shentsize = 0;
1088 elf.e_shnum = 0;
1089 elf.e_shstrndx = 0;
1090
1091 fs = get_fs();
1092 set_fs(KERNEL_DS);
1093
1094 has_dumped = 1;
1095 current->flags |= PF_DUMPCORE;
1096
1097 DUMP_WRITE(&elf, sizeof(elf));
1098 offset += sizeof(elf);
1099 offset += (segs+1) * sizeof(struct elf_phdr);
1100
1101
1102
1103
1104
1105 memset(&psinfo, 0, sizeof(psinfo));
1106 memset(&prstatus, 0, sizeof(prstatus));
1107
1108 notes[0].name = "CORE";
1109 notes[0].type = NT_PRSTATUS;
1110 notes[0].datasz = sizeof(prstatus);
1111 notes[0].data = &prstatus;
1112 prstatus.pr_info.si_signo = prstatus.pr_cursig = signr;
1113 prstatus.pr_sigpend = current->signal.sig[0];
1114 prstatus.pr_sighold = current->blocked.sig[0];
1115 psinfo.pr_pid = prstatus.pr_pid = current->pid;
1116 psinfo.pr_ppid = prstatus.pr_ppid = current->p_pptr->pid;
1117 psinfo.pr_pgrp = prstatus.pr_pgrp = current->pgrp;
1118 psinfo.pr_sid = prstatus.pr_sid = current->session;
1119 prstatus.pr_utime.tv_sec = CT_TO_SECS(current->times.tms_utime);
1120 prstatus.pr_utime.tv_usec = CT_TO_USECS(current->times.tms_utime);
1121 prstatus.pr_stime.tv_sec = CT_TO_SECS(current->times.tms_stime);
1122 prstatus.pr_stime.tv_usec = CT_TO_USECS(current->times.tms_stime);
1123 prstatus.pr_cutime.tv_sec = CT_TO_SECS(current->times.tms_cutime);
1124 prstatus.pr_cutime.tv_usec = CT_TO_USECS(current->times.tms_cutime);
1125 prstatus.pr_cstime.tv_sec = CT_TO_SECS(current->times.tms_cstime);
1126 prstatus.pr_cstime.tv_usec = CT_TO_USECS(current->times.tms_cstime);
1127
1128
1129
1130
1131
1132#ifdef ELF_CORE_COPY_REGS
1133 ELF_CORE_COPY_REGS(prstatus.pr_reg, regs)
1134#else
1135 if (sizeof(elf_gregset_t) != sizeof(struct pt_regs))
1136 {
1137 printk("sizeof(elf_gregset_t) (%ld) != sizeof(struct pt_regs) (%ld)\n",
1138 (long)sizeof(elf_gregset_t), (long)sizeof(struct pt_regs));
1139 }
1140 else
1141 *(struct pt_regs *)&prstatus.pr_reg = *regs;
1142#endif
1143
1144#ifdef DEBUG
1145 dump_regs("Passed in regs", (elf_greg_t *)regs);
1146 dump_regs("prstatus regs", (elf_greg_t *)&prstatus.pr_reg);
1147#endif
1148
1149 notes[1].name = "CORE";
1150 notes[1].type = NT_PRPSINFO;
1151 notes[1].datasz = sizeof(psinfo);
1152 notes[1].data = &psinfo;
1153 i = current->state ? ffz(~current->state) + 1 : 0;
1154 psinfo.pr_state = i;
1155 psinfo.pr_sname = (i < 0 || i > 5) ? '.' : "RSDZTD"[i];
1156 psinfo.pr_zomb = psinfo.pr_sname == 'Z';
1157 psinfo.pr_nice = current->priority-15;
1158 psinfo.pr_flag = current->flags;
1159 psinfo.pr_uid = current->uid;
1160 psinfo.pr_gid = current->gid;
1161 {
1162 int i, len;
1163
1164 set_fs(fs);
1165
1166 len = current->mm->arg_end - current->mm->arg_start;
1167 if (len < 0 || len >= ELF_PRARGSZ)
1168 len = ELF_PRARGSZ-1;
1169 copy_from_user(&psinfo.pr_psargs,
1170 (const char *)current->mm->arg_start, len);
1171 for(i = 0; i < len; i++)
1172 if (psinfo.pr_psargs[i] == 0)
1173 psinfo.pr_psargs[i] = ' ';
1174 psinfo.pr_psargs[len] = 0;
1175
1176 set_fs(KERNEL_DS);
1177 }
1178 strncpy(psinfo.pr_fname, current->comm, sizeof(psinfo.pr_fname));
1179
1180 notes[2].name = "CORE";
1181 notes[2].type = NT_TASKSTRUCT;
1182 notes[2].datasz = sizeof(*current);
1183 notes[2].data = current;
1184
1185
1186 prstatus.pr_fpvalid = dump_fpu (regs, &fpu);
1187 if (!prstatus.pr_fpvalid)
1188 {
1189 numnote--;
1190 }
1191 else
1192 {
1193 notes[3].name = "CORE";
1194 notes[3].type = NT_PRFPREG;
1195 notes[3].datasz = sizeof(fpu);
1196 notes[3].data = &fpu;
1197 }
1198
1199
1200 {
1201 struct elf_phdr phdr;
1202 int sz = 0;
1203
1204 for(i = 0; i < numnote; i++)
1205 sz += notesize(¬es[i]);
1206
1207 phdr.p_type = PT_NOTE;
1208 phdr.p_offset = offset;
1209 phdr.p_vaddr = 0;
1210 phdr.p_paddr = 0;
1211 phdr.p_filesz = sz;
1212 phdr.p_memsz = 0;
1213 phdr.p_flags = 0;
1214 phdr.p_align = 0;
1215
1216 offset += phdr.p_filesz;
1217 DUMP_WRITE(&phdr, sizeof(phdr));
1218 }
1219
1220
1221 dataoff = offset = roundup(offset, ELF_EXEC_PAGESIZE);
1222
1223
1224 for(vma = current->mm->mmap; vma != NULL; vma = vma->vm_next) {
1225 struct elf_phdr phdr;
1226 size_t sz;
1227
1228 sz = vma->vm_end - vma->vm_start;
1229
1230 phdr.p_type = PT_LOAD;
1231 phdr.p_offset = offset;
1232 phdr.p_vaddr = vma->vm_start;
1233 phdr.p_paddr = 0;
1234 phdr.p_filesz = maydump(vma) ? sz : 0;
1235 phdr.p_memsz = sz;
1236 offset += phdr.p_filesz;
1237 phdr.p_flags = vma->vm_flags & VM_READ ? PF_R : 0;
1238 if (vma->vm_flags & VM_WRITE) phdr.p_flags |= PF_W;
1239 if (vma->vm_flags & VM_EXEC) phdr.p_flags |= PF_X;
1240 phdr.p_align = ELF_EXEC_PAGESIZE;
1241
1242 DUMP_WRITE(&phdr, sizeof(phdr));
1243 }
1244
1245 for(i = 0; i < numnote; i++)
1246 if (!writenote(¬es[i], file))
1247 goto close_coredump;
1248
1249 set_fs(fs);
1250
1251 DUMP_SEEK(dataoff);
1252
1253 for(vma = current->mm->mmap; vma != NULL; vma = vma->vm_next) {
1254 unsigned long addr;
1255
1256 if (!maydump(vma))
1257 continue;
1258#ifdef DEBUG
1259 printk("elf_core_dump: writing %08lx %lx\n", addr, len);
1260#endif
1261 for (addr = vma->vm_start;
1262 addr < vma->vm_end;
1263 addr += PAGE_SIZE) {
1264 pgd_t *pgd;
1265 pmd_t *pmd;
1266 pte_t *pte;
1267
1268 pgd = pgd_offset(vma->vm_mm, addr);
1269 pmd = pmd_alloc(pgd, addr);
1270
1271 if (!pmd)
1272 goto end_coredump;
1273 pte = pte_alloc(pmd, addr);
1274 if (!pte)
1275 goto end_coredump;
1276 if (!pte_present(*pte) &&
1277 pte_none(*pte)) {
1278 DUMP_SEEK (file->f_pos + PAGE_SIZE);
1279 } else {
1280 DUMP_WRITE((void*)addr, PAGE_SIZE);
1281 }
1282 }
1283 }
1284
1285 if ((off_t) file->f_pos != offset) {
1286
1287 printk("elf_core_dump: file->f_pos (%ld) != offset (%ld)\n",
1288 (off_t) file->f_pos, offset);
1289 }
1290
1291 close_coredump:
1292 end_coredump:
1293 set_fs(fs);
1294 return has_dumped;
1295}
1296#endif
1297
1298int __init init_elf_binfmt(void)
1299{
1300 return register_binfmt(&elf_format);
1301}
1302
1303#ifdef MODULE
1304
1305int init_module(void)
1306{
1307
1308
1309
1310
1311 return init_elf_binfmt();
1312}
1313
1314
1315void cleanup_module( void)
1316{
1317
1318 unregister_binfmt(&elf_format);
1319}
1320#endif
1321