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