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